From 74c6021e8de1853099260f9de301c6ca63592a7b Mon Sep 17 00:00:00 2001 From: Garrett Brown Date: Sun, 16 Aug 2020 06:34:37 -0400 Subject: [PATCH 01/57] Starting box2d update --- CMakeLists.txt | 160 ++-- src/libraries/Box2D/Box2D.h | 103 ++- .../Box2D/Collision/Shapes/b2ChainShape.h | 105 --- .../Box2D/Collision/Shapes/b2CircleShape.h | 91 --- .../Box2D/Collision/Shapes/b2EdgeShape.h | 74 -- .../Box2D/Collision/b2CollideEdge.cpp | 698 ---------------- .../Box2D/Collision/b2TimeOfImpact.h | 58 -- .../{b2BroadPhase.cpp => b2_broad_phase.cpp} | 49 +- .../b2ChainShape.cpp => b2_chain_shape.cpp} | 96 +-- .../b2CircleShape.cpp => b2_circle_shape.cpp} | 54 +- ...ollideCircle.cpp => b2_collide_circle.cpp} | 64 +- .../Box2D/Collision/b2_collide_edge.cpp | 524 ++++++++++++ ...lidePolygon.cpp => b2_collide_polygon.cpp} | 70 +- .../{b2Collision.cpp => b2_collision.cpp} | 88 +- .../{b2Distance.cpp => b2_distance.cpp} | 277 +++++-- ...{b2DynamicTree.cpp => b2_dynamic_tree.cpp} | 129 +-- .../b2EdgeShape.cpp => b2_edge_shape.cpp} | 74 +- ...2PolygonShape.cpp => b2_polygon_shape.cpp} | 130 ++- ...TimeOfImpact.cpp => b2_time_of_impact.cpp} | 112 +-- src/libraries/Box2D/Common/b2BlockAllocator.h | 62 -- src/libraries/Box2D/Common/b2Draw.cpp | 44 - src/libraries/Box2D/Common/b2Draw.h | 86 -- src/libraries/Box2D/Common/b2GrowableStack.h | 85 -- src/libraries/Box2D/Common/b2Math.cpp | 94 --- src/libraries/Box2D/Common/b2Settings.cpp | 52 -- .../Box2D/Common/b2StackAllocator.cpp | 83 -- src/libraries/Box2D/Common/b2StackAllocator.h | 60 -- src/libraries/Box2D/Common/b2Timer.cpp | 101 --- src/libraries/Box2D/Common/b2Timer.h | 50 -- ...ckAllocator.cpp => b2_block_allocator.cpp} | 120 +-- src/libraries/Box2D/Common/b2_draw.cpp | 47 ++ src/libraries/Box2D/Common/b2_math.cpp | 98 +++ src/libraries/Box2D/Common/b2_settings.cpp | 77 ++ .../Box2D/Common/b2_stack_allocator.cpp | 87 ++ src/libraries/Box2D/Common/b2_timer.cpp | 125 +++ .../Contacts/b2ChainAndCircleContact.cpp | 53 -- .../Contacts/b2ChainAndCircleContact.h | 39 - .../Contacts/b2ChainAndPolygonContact.cpp | 53 -- .../Contacts/b2ChainAndPolygonContact.h | 39 - .../Dynamics/Contacts/b2CircleContact.cpp | 52 -- .../Box2D/Dynamics/Contacts/b2CircleContact.h | 39 - .../Box2D/Dynamics/Contacts/b2ContactSolver.h | 95 --- .../Contacts/b2EdgeAndCircleContact.cpp | 49 -- .../Contacts/b2EdgeAndCircleContact.h | 39 - .../Contacts/b2EdgeAndPolygonContact.cpp | 49 -- .../Contacts/b2EdgeAndPolygonContact.h | 39 - .../Contacts/b2PolygonAndCircleContact.cpp | 49 -- .../Contacts/b2PolygonAndCircleContact.h | 38 - .../Dynamics/Contacts/b2PolygonContact.cpp | 52 -- .../Dynamics/Contacts/b2PolygonContact.h | 39 - .../Box2D/Dynamics/Joints/b2DistanceJoint.h | 169 ---- .../Box2D/Dynamics/Joints/b2FrictionJoint.h | 119 --- .../Box2D/Dynamics/Joints/b2GearJoint.h | 125 --- .../Box2D/Dynamics/Joints/b2Joint.cpp | 211 ----- .../Box2D/Dynamics/Joints/b2MotorJoint.h | 133 --- .../Box2D/Dynamics/Joints/b2MouseJoint.h | 129 --- .../Dynamics/Joints/b2PrismaticJoint.cpp | 629 -------------- .../Box2D/Dynamics/Joints/b2RevoluteJoint.cpp | 502 ------------ .../Box2D/Dynamics/Joints/b2RopeJoint.h | 114 --- .../Box2D/Dynamics/Joints/b2WeldJoint.h | 126 --- .../Box2D/Dynamics/Joints/b2WheelJoint.cpp | 419 ---------- .../Box2D/Dynamics/Joints/b2WheelJoint.h | 210 ----- .../Box2D/Dynamics/b2ContactManager.h | 52 -- src/libraries/Box2D/Dynamics/b2TimeStep.h | 70 -- .../Box2D/Dynamics/b2WorldCallbacks.cpp | 36 - .../Dynamics/{b2Body.cpp => b2_body.cpp} | 189 +++-- .../Dynamics/b2_chain_circle_contact.cpp | 57 ++ .../Box2D/Dynamics/b2_chain_circle_contact.h | 43 + .../Dynamics/b2_chain_polygon_contact.cpp | 57 ++ .../Box2D/Dynamics/b2_chain_polygon_contact.h | 43 + .../Box2D/Dynamics/b2_circle_contact.cpp | 56 ++ .../Box2D/Dynamics/b2_circle_contact.h | 43 + .../b2Contact.cpp => b2_contact.cpp} | 96 +-- ...tactManager.cpp => b2_contact_manager.cpp} | 73 +- ...ontactSolver.cpp => b2_contact_solver.cpp} | 218 ++--- .../Box2D/Dynamics/b2_contact_solver.h | 99 +++ ...istanceJoint.cpp => b2_distance_joint.cpp} | 132 +-- .../Box2D/Dynamics/b2_edge_circle_contact.cpp | 54 ++ .../Box2D/Dynamics/b2_edge_circle_contact.h | 43 + .../Dynamics/b2_edge_polygon_contact.cpp | 54 ++ .../Box2D/Dynamics/b2_edge_polygon_contact.h | 43 + .../{b2Fixture.cpp => b2_fixture.cpp} | 149 ++-- ...rictionJoint.cpp => b2_friction_joint.cpp} | 106 +-- .../b2GearJoint.cpp => b2_gear_joint.cpp} | 132 +-- .../Dynamics/{b2Island.cpp => b2_island.cpp} | 101 +-- .../Dynamics/{b2Island.h => b2_island.h} | 44 +- src/libraries/Box2D/Dynamics/b2_joint.cpp | 313 +++++++ .../b2MotorJoint.cpp => b2_motor_joint.cpp} | 131 +-- .../b2MouseJoint.cpp => b2_mouse_joint.cpp} | 112 +-- .../Dynamics/b2_polygon_circle_contact.cpp | 54 ++ .../Dynamics/b2_polygon_circle_contact.h | 42 + .../Box2D/Dynamics/b2_polygon_contact.cpp | 57 ++ .../Box2D/Dynamics/b2_polygon_contact.h | 43 + .../Box2D/Dynamics/b2_prismatic_joint.cpp | 644 +++++++++++++++ .../b2PulleyJoint.cpp => b2_pulley_joint.cpp} | 136 ++-- .../Box2D/Dynamics/b2_revolute_joint.cpp | 501 ++++++++++++ .../b2RopeJoint.cpp => b2_rope_joint.cpp} | 119 ++- .../b2WeldJoint.cpp => b2_weld_joint.cpp} | 130 +-- .../Box2D/Dynamics/b2_wheel_joint.cpp | 672 +++++++++++++++ .../Dynamics/{b2World.cpp => b2_world.cpp} | 285 +++---- .../Box2D/Dynamics/b2_world_callbacks.cpp | 40 + src/libraries/Box2D/Rope/b2Rope.cpp | 259 ------ src/libraries/Box2D/Rope/b2Rope.h | 115 --- src/libraries/Box2D/Rope/b2_rope.cpp | 769 ++++++++++++++++++ src/libraries/Box2D/b2_block_allocator.h | 59 ++ .../Box2D/{Dynamics/b2Body.h => b2_body.h} | 217 ++--- .../b2BroadPhase.h => b2_broad_phase.h} | 106 +-- src/libraries/Box2D/b2_chain_shape.h | 100 +++ src/libraries/Box2D/b2_circle_shape.h | 66 ++ .../b2Collision.h => b2_collision.h} | 64 +- .../Contacts/b2Contact.h => b2_contact.h} | 88 +- src/libraries/Box2D/b2_contact_manager.h | 56 ++ .../{Collision/b2Distance.h => b2_distance.h} | 81 +- src/libraries/Box2D/b2_distance_joint.h | 140 ++++ src/libraries/Box2D/b2_draw.h | 101 +++ .../b2DynamicTree.h => b2_dynamic_tree.h} | 67 +- src/libraries/Box2D/b2_edge_shape.h | 85 ++ .../{Dynamics/b2Fixture.h => b2_fixture.h} | 87 +- src/libraries/Box2D/b2_friction_joint.h | 123 +++ src/libraries/Box2D/b2_gear_joint.h | 129 +++ src/libraries/Box2D/b2_growable_stack.h | 90 ++ .../{Dynamics/Joints/b2Joint.h => b2_joint.h} | 82 +- .../Box2D/{Common/b2Math.h => b2_math.h} | 170 ++-- src/libraries/Box2D/b2_motor_joint.h | 137 ++++ src/libraries/Box2D/b2_mouse_joint.h | 133 +++ .../b2PolygonShape.h => b2_polygon_shape.h} | 71 +- ...2PrismaticJoint.h => b2_prismatic_joint.h} | 128 +-- .../b2PulleyJoint.h => b2_pulley_joint.h} | 98 +-- .../b2RevoluteJoint.h => b2_revolute_joint.h} | 136 ++-- src/libraries/Box2D/b2_rope.h | 150 ++++ src/libraries/Box2D/b2_rope_joint.h | 118 +++ .../{Common/b2Settings.h => b2_settings.h} | 56 +- .../Shapes/b2Shape.h => b2_shape.h} | 56 +- src/libraries/Box2D/b2_stack_allocator.h | 64 ++ src/libraries/Box2D/b2_time_of_impact.h | 62 ++ src/libraries/Box2D/b2_time_step.h | 73 ++ src/libraries/Box2D/b2_timer.h | 54 ++ src/libraries/Box2D/b2_weld_joint.h | 132 +++ src/libraries/Box2D/b2_wheel_joint.h | 239 ++++++ .../Box2D/{Dynamics/b2World.h => b2_world.h} | 96 +-- ...2WorldCallbacks.h => b2_world_callbacks.h} | 49 +- src/modules/physics/box2d/Body.cpp | 4 +- src/modules/physics/box2d/ChainShape.cpp | 32 +- src/modules/physics/box2d/DistanceJoint.cpp | 8 +- src/modules/physics/box2d/EdgeShape.cpp | 30 +- src/modules/physics/box2d/Joint.cpp | 2 +- src/modules/physics/box2d/MouseJoint.cpp | 8 +- src/modules/physics/box2d/Physics.cpp | 28 +- src/modules/physics/box2d/PolygonShape.cpp | 4 +- src/modules/physics/box2d/WeldJoint.cpp | 8 +- src/modules/physics/box2d/WheelJoint.cpp | 10 +- src/modules/physics/box2d/World.cpp | 4 +- src/modules/physics/box2d/World.h | 2 +- 153 files changed, 9634 insertions(+), 8518 deletions(-) delete mode 100644 src/libraries/Box2D/Collision/Shapes/b2ChainShape.h delete mode 100644 src/libraries/Box2D/Collision/Shapes/b2CircleShape.h delete mode 100644 src/libraries/Box2D/Collision/Shapes/b2EdgeShape.h delete mode 100644 src/libraries/Box2D/Collision/b2CollideEdge.cpp delete mode 100644 src/libraries/Box2D/Collision/b2TimeOfImpact.h rename src/libraries/Box2D/Collision/{b2BroadPhase.cpp => b2_broad_phase.cpp} (60%) rename src/libraries/Box2D/Collision/{Shapes/b2ChainShape.cpp => b2_chain_shape.cpp} (60%) rename src/libraries/Box2D/Collision/{Shapes/b2CircleShape.cpp => b2_circle_shape.cpp} (56%) rename src/libraries/Box2D/Collision/{b2CollideCircle.cpp => b2_collide_circle.cpp} (63%) create mode 100644 src/libraries/Box2D/Collision/b2_collide_edge.cpp rename src/libraries/Box2D/Collision/{b2CollidePolygon.cpp => b2_collide_polygon.cpp} (72%) rename src/libraries/Box2D/Collision/{b2Collision.cpp => b2_collision.cpp} (67%) rename src/libraries/Box2D/Collision/{b2Distance.cpp => b2_distance.cpp} (64%) rename src/libraries/Box2D/Collision/{b2DynamicTree.cpp => b2_dynamic_tree.cpp} (83%) rename src/libraries/Box2D/Collision/{Shapes/b2EdgeShape.cpp => b2_edge_shape.cpp} (52%) rename src/libraries/Box2D/Collision/{Shapes/b2PolygonShape.cpp => b2_polygon_shape.cpp} (74%) rename src/libraries/Box2D/Collision/{b2TimeOfImpact.cpp => b2_time_of_impact.cpp} (78%) delete mode 100644 src/libraries/Box2D/Common/b2BlockAllocator.h delete mode 100644 src/libraries/Box2D/Common/b2Draw.cpp delete mode 100644 src/libraries/Box2D/Common/b2Draw.h delete mode 100644 src/libraries/Box2D/Common/b2GrowableStack.h delete mode 100644 src/libraries/Box2D/Common/b2Math.cpp delete mode 100644 src/libraries/Box2D/Common/b2Settings.cpp delete mode 100644 src/libraries/Box2D/Common/b2StackAllocator.cpp delete mode 100644 src/libraries/Box2D/Common/b2StackAllocator.h delete mode 100644 src/libraries/Box2D/Common/b2Timer.cpp delete mode 100644 src/libraries/Box2D/Common/b2Timer.h rename src/libraries/Box2D/Common/{b2BlockAllocator.cpp => b2_block_allocator.cpp} (59%) create mode 100644 src/libraries/Box2D/Common/b2_draw.cpp create mode 100644 src/libraries/Box2D/Common/b2_math.cpp create mode 100644 src/libraries/Box2D/Common/b2_settings.cpp create mode 100644 src/libraries/Box2D/Common/b2_stack_allocator.cpp create mode 100644 src/libraries/Box2D/Common/b2_timer.cpp delete mode 100644 src/libraries/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp delete mode 100644 src/libraries/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.h delete mode 100644 src/libraries/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp delete mode 100644 src/libraries/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.h delete mode 100644 src/libraries/Box2D/Dynamics/Contacts/b2CircleContact.cpp delete mode 100644 src/libraries/Box2D/Dynamics/Contacts/b2CircleContact.h delete mode 100644 src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.h delete mode 100644 src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.cpp delete mode 100644 src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.h delete mode 100644 src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp delete mode 100644 src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.h delete mode 100644 src/libraries/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp delete mode 100644 src/libraries/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h delete mode 100644 src/libraries/Box2D/Dynamics/Contacts/b2PolygonContact.cpp delete mode 100644 src/libraries/Box2D/Dynamics/Contacts/b2PolygonContact.h delete mode 100644 src/libraries/Box2D/Dynamics/Joints/b2DistanceJoint.h delete mode 100644 src/libraries/Box2D/Dynamics/Joints/b2FrictionJoint.h delete mode 100644 src/libraries/Box2D/Dynamics/Joints/b2GearJoint.h delete mode 100644 src/libraries/Box2D/Dynamics/Joints/b2Joint.cpp delete mode 100644 src/libraries/Box2D/Dynamics/Joints/b2MotorJoint.h delete mode 100644 src/libraries/Box2D/Dynamics/Joints/b2MouseJoint.h delete mode 100644 src/libraries/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp delete mode 100644 src/libraries/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp delete mode 100644 src/libraries/Box2D/Dynamics/Joints/b2RopeJoint.h delete mode 100644 src/libraries/Box2D/Dynamics/Joints/b2WeldJoint.h delete mode 100644 src/libraries/Box2D/Dynamics/Joints/b2WheelJoint.cpp delete mode 100644 src/libraries/Box2D/Dynamics/Joints/b2WheelJoint.h delete mode 100644 src/libraries/Box2D/Dynamics/b2ContactManager.h delete mode 100644 src/libraries/Box2D/Dynamics/b2TimeStep.h delete mode 100644 src/libraries/Box2D/Dynamics/b2WorldCallbacks.cpp rename src/libraries/Box2D/Dynamics/{b2Body.cpp => b2_body.cpp} (70%) create mode 100644 src/libraries/Box2D/Dynamics/b2_chain_circle_contact.cpp create mode 100644 src/libraries/Box2D/Dynamics/b2_chain_circle_contact.h create mode 100644 src/libraries/Box2D/Dynamics/b2_chain_polygon_contact.cpp create mode 100644 src/libraries/Box2D/Dynamics/b2_chain_polygon_contact.h create mode 100644 src/libraries/Box2D/Dynamics/b2_circle_contact.cpp create mode 100644 src/libraries/Box2D/Dynamics/b2_circle_contact.h rename src/libraries/Box2D/Dynamics/{Contacts/b2Contact.cpp => b2_contact.cpp} (72%) rename src/libraries/Box2D/Dynamics/{b2ContactManager.cpp => b2_contact_manager.cpp} (78%) rename src/libraries/Box2D/Dynamics/{Contacts/b2ContactSolver.cpp => b2_contact_solver.cpp} (79%) create mode 100644 src/libraries/Box2D/Dynamics/b2_contact_solver.h rename src/libraries/Box2D/Dynamics/{Joints/b2DistanceJoint.cpp => b2_distance_joint.cpp} (59%) create mode 100644 src/libraries/Box2D/Dynamics/b2_edge_circle_contact.cpp create mode 100644 src/libraries/Box2D/Dynamics/b2_edge_circle_contact.h create mode 100644 src/libraries/Box2D/Dynamics/b2_edge_polygon_contact.cpp create mode 100644 src/libraries/Box2D/Dynamics/b2_edge_polygon_contact.h rename src/libraries/Box2D/Dynamics/{b2Fixture.cpp => b2_fixture.cpp} (54%) rename src/libraries/Box2D/Dynamics/{Joints/b2FrictionJoint.cpp => b2_friction_joint.cpp} (62%) rename src/libraries/Box2D/Dynamics/{Joints/b2GearJoint.cpp => b2_gear_joint.cpp} (74%) rename src/libraries/Box2D/Dynamics/{b2Island.cpp => b2_island.cpp} (86%) rename src/libraries/Box2D/Dynamics/{b2Island.h => b2_island.h} (54%) create mode 100644 src/libraries/Box2D/Dynamics/b2_joint.cpp rename src/libraries/Box2D/Dynamics/{Joints/b2MotorJoint.cpp => b2_motor_joint.cpp} (61%) rename src/libraries/Box2D/Dynamics/{Joints/b2MouseJoint.cpp => b2_mouse_joint.cpp} (56%) create mode 100644 src/libraries/Box2D/Dynamics/b2_polygon_circle_contact.cpp create mode 100644 src/libraries/Box2D/Dynamics/b2_polygon_circle_contact.h create mode 100644 src/libraries/Box2D/Dynamics/b2_polygon_contact.cpp create mode 100644 src/libraries/Box2D/Dynamics/b2_polygon_contact.h create mode 100644 src/libraries/Box2D/Dynamics/b2_prismatic_joint.cpp rename src/libraries/Box2D/Dynamics/{Joints/b2PulleyJoint.cpp => b2_pulley_joint.cpp} (62%) create mode 100644 src/libraries/Box2D/Dynamics/b2_revolute_joint.cpp rename src/libraries/Box2D/Dynamics/{Joints/b2RopeJoint.cpp => b2_rope_joint.cpp} (57%) rename src/libraries/Box2D/Dynamics/{Joints/b2WeldJoint.cpp => b2_weld_joint.cpp} (66%) create mode 100644 src/libraries/Box2D/Dynamics/b2_wheel_joint.cpp rename src/libraries/Box2D/Dynamics/{b2World.cpp => b2_world.cpp} (82%) create mode 100644 src/libraries/Box2D/Dynamics/b2_world_callbacks.cpp delete mode 100644 src/libraries/Box2D/Rope/b2Rope.cpp delete mode 100644 src/libraries/Box2D/Rope/b2Rope.h create mode 100644 src/libraries/Box2D/Rope/b2_rope.cpp create mode 100644 src/libraries/Box2D/b2_block_allocator.h rename src/libraries/Box2D/{Dynamics/b2Body.h => b2_body.h} (80%) rename src/libraries/Box2D/{Collision/b2BroadPhase.h => b2_broad_phase.h} (72%) create mode 100644 src/libraries/Box2D/b2_chain_shape.h create mode 100644 src/libraries/Box2D/b2_circle_shape.h rename src/libraries/Box2D/{Collision/b2Collision.h => b2_collision.h} (81%) rename src/libraries/Box2D/{Dynamics/Contacts/b2Contact.h => b2_contact.h} (78%) create mode 100644 src/libraries/Box2D/b2_contact_manager.h rename src/libraries/Box2D/{Collision/b2Distance.h => b2_distance.h} (52%) create mode 100644 src/libraries/Box2D/b2_distance_joint.h create mode 100644 src/libraries/Box2D/b2_draw.h rename src/libraries/Box2D/{Collision/b2DynamicTree.h => b2_dynamic_tree.h} (78%) create mode 100644 src/libraries/Box2D/b2_edge_shape.h rename src/libraries/Box2D/{Dynamics/b2Fixture.h => b2_fixture.h} (79%) create mode 100644 src/libraries/Box2D/b2_friction_joint.h create mode 100644 src/libraries/Box2D/b2_gear_joint.h create mode 100644 src/libraries/Box2D/b2_growable_stack.h rename src/libraries/Box2D/{Dynamics/Joints/b2Joint.h => b2_joint.h} (66%) rename src/libraries/Box2D/{Common/b2Math.h => b2_math.h} (78%) create mode 100644 src/libraries/Box2D/b2_motor_joint.h create mode 100644 src/libraries/Box2D/b2_mouse_joint.h rename src/libraries/Box2D/{Collision/Shapes/b2PolygonShape.h => b2_polygon_shape.h} (51%) rename src/libraries/Box2D/{Dynamics/Joints/b2PrismaticJoint.h => b2_prismatic_joint.h} (58%) rename src/libraries/Box2D/{Dynamics/Joints/b2PulleyJoint.h => b2_pulley_joint.h} (56%) rename src/libraries/Box2D/{Dynamics/Joints/b2RevoluteJoint.h => b2_revolute_joint.h} (55%) create mode 100644 src/libraries/Box2D/b2_rope.h create mode 100644 src/libraries/Box2D/b2_rope_joint.h rename src/libraries/Box2D/{Common/b2Settings.h => b2_settings.h} (74%) rename src/libraries/Box2D/{Collision/Shapes/b2Shape.h => b2_shape.h} (62%) create mode 100644 src/libraries/Box2D/b2_stack_allocator.h create mode 100644 src/libraries/Box2D/b2_time_of_impact.h create mode 100644 src/libraries/Box2D/b2_time_step.h create mode 100644 src/libraries/Box2D/b2_timer.h create mode 100644 src/libraries/Box2D/b2_weld_joint.h create mode 100644 src/libraries/Box2D/b2_wheel_joint.h rename src/libraries/Box2D/{Dynamics/b2World.h => b2_world.h} (82%) rename src/libraries/Box2D/{Dynamics/b2WorldCallbacks.h => b2_world_callbacks.h} (76%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 541b0ea14..d1290e393 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1068,126 +1068,77 @@ set(LOVE_SRC_3P_BOX2D_ROOT ) set(LOVE_SRC_3P_BOX2D_COLLISION - src/libraries/Box2D/Collision/b2BroadPhase.cpp - src/libraries/Box2D/Collision/b2BroadPhase.h - src/libraries/Box2D/Collision/b2CollideCircle.cpp - src/libraries/Box2D/Collision/b2CollideEdge.cpp - src/libraries/Box2D/Collision/b2CollidePolygon.cpp - src/libraries/Box2D/Collision/b2Collision.cpp - src/libraries/Box2D/Collision/b2Collision.h - src/libraries/Box2D/Collision/b2Distance.cpp - src/libraries/Box2D/Collision/b2Distance.h - src/libraries/Box2D/Collision/b2DynamicTree.cpp - src/libraries/Box2D/Collision/b2DynamicTree.h - src/libraries/Box2D/Collision/b2TimeOfImpact.cpp - src/libraries/Box2D/Collision/b2TimeOfImpact.h -) - -set(LOVE_SRC_3P_BOX2D_COLLISION_SHAPES - src/libraries/Box2D/Collision/Shapes/b2ChainShape.cpp - src/libraries/Box2D/Collision/Shapes/b2ChainShape.h - src/libraries/Box2D/Collision/Shapes/b2CircleShape.cpp - src/libraries/Box2D/Collision/Shapes/b2CircleShape.h - src/libraries/Box2D/Collision/Shapes/b2EdgeShape.cpp - src/libraries/Box2D/Collision/Shapes/b2EdgeShape.h - src/libraries/Box2D/Collision/Shapes/b2PolygonShape.cpp - src/libraries/Box2D/Collision/Shapes/b2PolygonShape.h - src/libraries/Box2D/Collision/Shapes/b2Shape.h + src/libraries/Box2D/collision/b2_broad_phase.cpp + src/libraries/Box2D/collision/b2_chain_shape.cpp + src/libraries/Box2D/collision/b2_circle_shape.cpp + src/libraries/Box2D/collision/b2_collide_circle.cpp + src/libraries/Box2D/collision/b2_collide_edge.cpp + src/libraries/Box2D/collision/b2_collide_polygon.cpp + src/libraries/Box2D/collision/b2_collision.cpp + src/libraries/Box2D/collision/b2_distance.cpp + src/libraries/Box2D/collision/b2_dynamic_tree.cpp + src/libraries/Box2D/collision/b2_edge_shape.cpp + src/libraries/Box2D/collision/b2_polygon_shape.cpp + src/libraries/Box2D/collision/b2_time_of_impact.cpp ) set(LOVE_SRC_3P_BOX2D_COMMON - src/libraries/Box2D/Common/b2BlockAllocator.cpp - src/libraries/Box2D/Common/b2BlockAllocator.h - src/libraries/Box2D/Common/b2Draw.cpp - src/libraries/Box2D/Common/b2Draw.h - src/libraries/Box2D/Common/b2GrowableStack.h - src/libraries/Box2D/Common/b2Math.cpp - src/libraries/Box2D/Common/b2Math.h - src/libraries/Box2D/Common/b2Settings.cpp - src/libraries/Box2D/Common/b2Settings.h - src/libraries/Box2D/Common/b2StackAllocator.cpp - src/libraries/Box2D/Common/b2StackAllocator.h - src/libraries/Box2D/Common/b2Timer.cpp - src/libraries/Box2D/Common/b2Timer.h + src/libraries/Box2D/common/b2_block_allocator.cpp + src/libraries/Box2D/common/b2_draw.cpp + src/libraries/Box2D/common/b2_math.cpp + src/libraries/Box2D/common/b2_settings.cpp + src/libraries/Box2D/common/b2_stack_allocator.cpp + src/libraries/Box2D/common/b2_timer.cpp ) set(LOVE_SRC_3P_BOX2D_DYNAMICS - src/libraries/Box2D/Dynamics/b2Body.cpp - src/libraries/Box2D/Dynamics/b2Body.h - src/libraries/Box2D/Dynamics/b2ContactManager.cpp - src/libraries/Box2D/Dynamics/b2ContactManager.h - src/libraries/Box2D/Dynamics/b2Fixture.cpp - src/libraries/Box2D/Dynamics/b2Fixture.h - src/libraries/Box2D/Dynamics/b2Island.cpp - src/libraries/Box2D/Dynamics/b2Island.h - src/libraries/Box2D/Dynamics/b2TimeStep.h - src/libraries/Box2D/Dynamics/b2World.cpp - src/libraries/Box2D/Dynamics/b2World.h - src/libraries/Box2D/Dynamics/b2WorldCallbacks.cpp - src/libraries/Box2D/Dynamics/b2WorldCallbacks.h -) - -set(LOVE_SRC_3P_BOX2D_DYNAMICS_CONTACTS - src/libraries/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp - src/libraries/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.h - src/libraries/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp - src/libraries/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.h - src/libraries/Box2D/Dynamics/Contacts/b2CircleContact.cpp - src/libraries/Box2D/Dynamics/Contacts/b2CircleContact.h - src/libraries/Box2D/Dynamics/Contacts/b2Contact.cpp - src/libraries/Box2D/Dynamics/Contacts/b2Contact.h - src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.cpp - src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.h - src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.cpp - src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.h - src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp - src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.h - src/libraries/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp - src/libraries/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h - src/libraries/Box2D/Dynamics/Contacts/b2PolygonContact.cpp - src/libraries/Box2D/Dynamics/Contacts/b2PolygonContact.h -) - -set(LOVE_SRC_3P_BOX2D_DYNAMICS_JOINTS - src/libraries/Box2D/Dynamics/Joints/b2DistanceJoint.cpp - src/libraries/Box2D/Dynamics/Joints/b2DistanceJoint.h - src/libraries/Box2D/Dynamics/Joints/b2FrictionJoint.cpp - src/libraries/Box2D/Dynamics/Joints/b2FrictionJoint.h - src/libraries/Box2D/Dynamics/Joints/b2GearJoint.cpp - src/libraries/Box2D/Dynamics/Joints/b2GearJoint.h - src/libraries/Box2D/Dynamics/Joints/b2Joint.cpp - src/libraries/Box2D/Dynamics/Joints/b2Joint.h - src/libraries/Box2D/Dynamics/Joints/b2MotorJoint.cpp - src/libraries/Box2D/Dynamics/Joints/b2MotorJoint.h - src/libraries/Box2D/Dynamics/Joints/b2MouseJoint.cpp - src/libraries/Box2D/Dynamics/Joints/b2MouseJoint.h - src/libraries/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp - src/libraries/Box2D/Dynamics/Joints/b2PrismaticJoint.h - src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.cpp - src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.h - src/libraries/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp - src/libraries/Box2D/Dynamics/Joints/b2RevoluteJoint.h - src/libraries/Box2D/Dynamics/Joints/b2RopeJoint.cpp - src/libraries/Box2D/Dynamics/Joints/b2RopeJoint.h - src/libraries/Box2D/Dynamics/Joints/b2WeldJoint.cpp - src/libraries/Box2D/Dynamics/Joints/b2WeldJoint.h - src/libraries/Box2D/Dynamics/Joints/b2WheelJoint.cpp - src/libraries/Box2D/Dynamics/Joints/b2WheelJoint.h + src/libraries/Box2D/dynamics/b2_body.cpp + src/libraries/Box2D/dynamics/b2_chain_circle_contact.cpp + src/libraries/Box2D/dynamics/b2_chain_circle_contact.h + src/libraries/Box2D/dynamics/b2_chain_polygon_contact.cpp + src/libraries/Box2D/dynamics/b2_chain_polygon_contact.h + src/libraries/Box2D/dynamics/b2_circle_contact.cpp + src/libraries/Box2D/dynamics/b2_circle_contact.h + src/libraries/Box2D/dynamics/b2_contact.cpp + src/libraries/Box2D/dynamics/b2_contact_manager.cpp + src/libraries/Box2D/dynamics/b2_contact_solver.cpp + src/libraries/Box2D/dynamics/b2_contact_solver.h + src/libraries/Box2D/dynamics/b2_distance_joint.cpp + src/libraries/Box2D/dynamics/b2_edge_circle_contact.cpp + src/libraries/Box2D/dynamics/b2_edge_circle_contact.h + src/libraries/Box2D/dynamics/b2_edge_polygon_contact.cpp + src/libraries/Box2D/dynamics/b2_edge_polygon_contact.h + src/libraries/Box2D/dynamics/b2_fixture.cpp + src/libraries/Box2D/dynamics/b2_friction_joint.cpp + src/libraries/Box2D/dynamics/b2_gear_joint.cpp + src/libraries/Box2D/dynamics/b2_island.cpp + src/libraries/Box2D/dynamics/b2_island.h + src/libraries/Box2D/dynamics/b2_joint.cpp + src/libraries/Box2D/dynamics/b2_motor_joint.cpp + src/libraries/Box2D/dynamics/b2_mouse_joint.cpp + src/libraries/Box2D/dynamics/b2_polygon_circle_contact.cpp + src/libraries/Box2D/dynamics/b2_polygon_circle_contact.h + src/libraries/Box2D/dynamics/b2_polygon_contact.cpp + src/libraries/Box2D/dynamics/b2_polygon_contact.h + src/libraries/Box2D/dynamics/b2_prismatic_joint.cpp + src/libraries/Box2D/dynamics/b2_pulley_joint.cpp + src/libraries/Box2D/dynamics/b2_revolute_joint.cpp + src/libraries/Box2D/dynamics/b2_rope_joint.cpp + src/libraries/Box2D/dynamics/b2_weld_joint.cpp + src/libraries/Box2D/dynamics/b2_wheel_joint.cpp + src/libraries/Box2D/dynamics/b2_world.cpp + src/libraries/Box2D/dynamics/b2_world_callbacks.cpp ) set(LOVE_SRC_3P_BOX2D_ROPE - src/libraries/Box2D/Rope/b2Rope.cpp - src/libraries/Box2D/Rope/b2Rope.h + src/libraries/Box2D/rope/b2_rope.cpp ) set(LOVE_SRC_3P_BOX2D ${LOVE_SRC_3P_BOX2D_ROOT} ${LOVE_SRC_3P_BOX2D_COLLISION} - ${LOVE_SRC_3P_BOX2D_COLLISION_SHAPES} ${LOVE_SRC_3P_BOX2D_COMMON} ${LOVE_SRC_3P_BOX2D_DYNAMICS} - ${LOVE_SRC_3P_BOX2D_DYNAMICS_CONTACTS} - ${LOVE_SRC_3P_BOX2D_DYNAMICS_JOINTS} ${LOVE_SRC_3P_BOX2D_ROPE} ) @@ -1726,6 +1677,7 @@ set(LOVE_LIB_SRC include_directories( src src/libraries + src/libraries/Box2D src/modules ${LOVE_INCLUDE_DIRS} ) diff --git a/src/libraries/Box2D/Box2D.h b/src/libraries/Box2D/Box2D.h index 187046131..71db86c58 100644 --- a/src/libraries/Box2D/Box2D.h +++ b/src/libraries/Box2D/Box2D.h @@ -1,68 +1,59 @@ -/* -* 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. -*/ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 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 -#include -#include +#include "b2_settings.h" +#include "b2_draw.h" +#include "b2_timer.h" -#include -#include -#include -#include +#include "b2_chain_shape.h" +#include "b2_circle_shape.h" +#include "b2_edge_shape.h" +#include "b2_polygon_shape.h" -#include -#include -#include -#include +#include "b2_broad_phase.h" +#include "b2_dynamic_tree.h" -#include -#include -#include -#include -#include +#include "b2_body.h" +#include "b2_contact.h" +#include "b2_fixture.h" +#include "b2_time_step.h" +#include "b2_world.h" +#include "b2_world_callbacks.h" -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "b2_distance_joint.h" +#include "b2_friction_joint.h" +#include "b2_gear_joint.h" +#include "b2_motor_joint.h" +#include "b2_mouse_joint.h" +#include "b2_prismatic_joint.h" +#include "b2_pulley_joint.h" +#include "b2_revolute_joint.h" +#include "b2_rope_joint.h" +#include "b2_weld_joint.h" +#include "b2_wheel_joint.h" #endif diff --git a/src/libraries/Box2D/Collision/Shapes/b2ChainShape.h b/src/libraries/Box2D/Collision/Shapes/b2ChainShape.h deleted file mode 100644 index 44493c43d..000000000 --- a/src/libraries/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 - -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; - - /// @see b2Shape::GetChildCount - int32 GetChildCount() const; - - /// 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; - - /// Implement b2Shape. - bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, - const b2Transform& transform, int32 childIndex) const; - - /// @see b2Shape::ComputeAABB - void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const; - - /// Chains have zero mass. - /// @see b2Shape::ComputeMass - void ComputeMass(b2MassData* massData, float32 density) const; - - /// 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 = NULL; - m_count = 0; - m_hasPrevVertex = false; - m_hasNextVertex = false; -} - -#endif diff --git a/src/libraries/Box2D/Collision/Shapes/b2CircleShape.h b/src/libraries/Box2D/Collision/Shapes/b2CircleShape.h deleted file mode 100644 index 3209f924a..000000000 --- a/src/libraries/Box2D/Collision/Shapes/b2CircleShape.h +++ /dev/null @@ -1,91 +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 - -/// A circle shape. -class b2CircleShape : public b2Shape -{ -public: - b2CircleShape(); - - /// Implement b2Shape. - b2Shape* Clone(b2BlockAllocator* allocator) const; - - /// @see b2Shape::GetChildCount - int32 GetChildCount() const; - - /// Implement b2Shape. - bool TestPoint(const b2Transform& transform, const b2Vec2& p) const; - - /// Implement b2Shape. - bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, - const b2Transform& transform, int32 childIndex) const; - - /// @see b2Shape::ComputeAABB - void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const; - - /// @see b2Shape::ComputeMass - void ComputeMass(b2MassData* massData, float32 density) const; - - /// 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 { return 1; } - - /// Get a vertex by index. Used by b2Distance. - const b2Vec2& GetVertex(int32 index) const; - - /// Position - b2Vec2 m_p; -}; - -inline b2CircleShape::b2CircleShape() -{ - m_type = e_circle; - m_radius = 0.0f; - m_p.SetZero(); -} - -inline int32 b2CircleShape::GetSupport(const b2Vec2 &d) const -{ - B2_NOT_USED(d); - return 0; -} - -inline const b2Vec2& b2CircleShape::GetSupportVertex(const b2Vec2 &d) const -{ - B2_NOT_USED(d); - return m_p; -} - -inline const b2Vec2& b2CircleShape::GetVertex(int32 index) const -{ - B2_NOT_USED(index); - b2Assert(index == 0); - return m_p; -} - -#endif diff --git a/src/libraries/Box2D/Collision/Shapes/b2EdgeShape.h b/src/libraries/Box2D/Collision/Shapes/b2EdgeShape.h deleted file mode 100644 index 0acef8518..000000000 --- a/src/libraries/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 - -/// 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; - - /// @see b2Shape::GetChildCount - int32 GetChildCount() const; - - /// @see b2Shape::TestPoint - bool TestPoint(const b2Transform& transform, const b2Vec2& p) const; - - /// Implement b2Shape. - bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, - const b2Transform& transform, int32 childIndex) const; - - /// @see b2Shape::ComputeAABB - void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const; - - /// @see b2Shape::ComputeMass - void ComputeMass(b2MassData* massData, float32 density) const; - - /// 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/libraries/Box2D/Collision/b2CollideEdge.cpp b/src/libraries/Box2D/Collision/b2CollideEdge.cpp deleted file mode 100644 index 88e311c66..000000000 --- a/src/libraries/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 -#include -#include -#include - - -// 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 = 2.0f * b2_polygonRadius; - - 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(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(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(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(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/libraries/Box2D/Collision/b2TimeOfImpact.h b/src/libraries/Box2D/Collision/b2TimeOfImpact.h deleted file mode 100644 index 20620c1ee..000000000 --- a/src/libraries/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 -#include - -/// 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 collision. 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/libraries/Box2D/Collision/b2BroadPhase.cpp b/src/libraries/Box2D/Collision/b2_broad_phase.cpp similarity index 60% rename from src/libraries/Box2D/Collision/b2BroadPhase.cpp rename to src/libraries/Box2D/Collision/b2_broad_phase.cpp index f46e4d090..d063a3aa9 100644 --- a/src/libraries/Box2D/Collision/b2BroadPhase.cpp +++ b/src/libraries/Box2D/Collision/b2_broad_phase.cpp @@ -1,22 +1,26 @@ -/* -* 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. -*/ +// MIT License -#include +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_broad_phase.h" #include b2BroadPhase::b2BroadPhase() @@ -102,11 +106,18 @@ bool b2BroadPhase::QueryCallback(int32 proxyId) return true; } + const bool moved = m_tree.WasMoved(proxyId); + if (moved && proxyId > m_queryProxyId) + { + // Both proxies are moving. Avoid duplicate pairs. + return true; + } + // Grow the pair buffer as needed. if (m_pairCount == m_pairCapacity) { b2Pair* oldBuffer = m_pairBuffer; - m_pairCapacity *= 2; + m_pairCapacity = m_pairCapacity + (m_pairCapacity >> 1); m_pairBuffer = (b2Pair*)b2Alloc(m_pairCapacity * sizeof(b2Pair)); memcpy(m_pairBuffer, oldBuffer, m_pairCount * sizeof(b2Pair)); b2Free(oldBuffer); diff --git a/src/libraries/Box2D/Collision/Shapes/b2ChainShape.cpp b/src/libraries/Box2D/Collision/b2_chain_shape.cpp similarity index 60% rename from src/libraries/Box2D/Collision/Shapes/b2ChainShape.cpp rename to src/libraries/Box2D/Collision/b2_chain_shape.cpp index 0c7282cc1..b964a4303 100644 --- a/src/libraries/Box2D/Collision/Shapes/b2ChainShape.cpp +++ b/src/libraries/Box2D/Collision/b2_chain_shape.cpp @@ -1,23 +1,30 @@ -/* -* 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. -*/ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_chain_shape.h" +#include "box2d/b2_edge_shape.h" + +#include "box2d/b2_block_allocator.h" -#include -#include #include #include @@ -29,14 +36,19 @@ b2ChainShape::~b2ChainShape() void b2ChainShape::Clear() { b2Free(m_vertices); - m_vertices = NULL; + m_vertices = nullptr; m_count = 0; } void b2ChainShape::CreateLoop(const b2Vec2* vertices, int32 count) { - b2Assert(m_vertices == NULL && m_count == 0); + 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]; @@ -51,13 +63,11 @@ void b2ChainShape::CreateLoop(const b2Vec2* vertices, int32 count) 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) +void b2ChainShape::CreateChain(const b2Vec2* vertices, int32 count, const b2Vec2& prevVertex, const b2Vec2& nextVertex) { - b2Assert(m_vertices == NULL && m_count == 0); + b2Assert(m_vertices == nullptr && m_count == 0); b2Assert(count >= 2); for (int32 i = 1; i < count; ++i) { @@ -69,34 +79,15 @@ void b2ChainShape::CreateChain(const b2Vec2* vertices, int32 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; + clone->CreateChain(m_vertices, m_count, m_prevVertex, m_nextVertex); return clone; } @@ -114,27 +105,24 @@ void b2ChainShape::GetChildEdge(b2EdgeShape* edge, int32 index) const edge->m_vertex1 = m_vertices[index + 0]; edge->m_vertex2 = m_vertices[index + 1]; + edge->m_oneSided = true; 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; } } @@ -179,11 +167,15 @@ void b2ChainShape::ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childI b2Vec2 v1 = b2Mul(xf, m_vertices[i1]); b2Vec2 v2 = b2Mul(xf, m_vertices[i2]); - aabb->lowerBound = b2Min(v1, v2); - aabb->upperBound = b2Max(v1, v2); + 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 b2ChainShape::ComputeMass(b2MassData* massData, float32 density) const +void b2ChainShape::ComputeMass(b2MassData* massData, float density) const { B2_NOT_USED(density); diff --git a/src/libraries/Box2D/Collision/Shapes/b2CircleShape.cpp b/src/libraries/Box2D/Collision/b2_circle_shape.cpp similarity index 56% rename from src/libraries/Box2D/Collision/Shapes/b2CircleShape.cpp rename to src/libraries/Box2D/Collision/b2_circle_shape.cpp index 39d4ae999..ecc69293b 100644 --- a/src/libraries/Box2D/Collision/Shapes/b2CircleShape.cpp +++ b/src/libraries/Box2D/Collision/b2_circle_shape.cpp @@ -1,22 +1,28 @@ -/* -* 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. -*/ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_circle_shape.h" +#include "box2d/b2_block_allocator.h" -#include #include b2Shape* b2CircleShape::Clone(b2BlockAllocator* allocator) const @@ -50,13 +56,13 @@ bool b2CircleShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input b2Vec2 position = transform.p + b2Mul(transform.q, m_p); b2Vec2 s = input.p1 - position; - float32 b = b2Dot(s, s) - m_radius * m_radius; + float 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; + float c = b2Dot(s, r); + float rr = b2Dot(r, r); + float sigma = c * c - rr * b; // Check for negative discriminant and short segment. if (sigma < 0.0f || rr < b2_epsilon) @@ -65,7 +71,7 @@ bool b2CircleShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input } // Find the point of intersection of the line with the circle. - float32 a = -(c + b2Sqrt(sigma)); + float a = -(c + b2Sqrt(sigma)); // Is the intersection point on the segment? if (0.0f <= a && a <= input.maxFraction * rr) @@ -89,7 +95,7 @@ void b2CircleShape::ComputeAABB(b2AABB* aabb, const b2Transform& transform, int3 aabb->upperBound.Set(p.x + m_radius, p.y + m_radius); } -void b2CircleShape::ComputeMass(b2MassData* massData, float32 density) const +void b2CircleShape::ComputeMass(b2MassData* massData, float density) const { massData->mass = density * b2_pi * m_radius * m_radius; massData->center = m_p; diff --git a/src/libraries/Box2D/Collision/b2CollideCircle.cpp b/src/libraries/Box2D/Collision/b2_collide_circle.cpp similarity index 63% rename from src/libraries/Box2D/Collision/b2CollideCircle.cpp rename to src/libraries/Box2D/Collision/b2_collide_circle.cpp index 4181fd47c..469da5590 100644 --- a/src/libraries/Box2D/Collision/b2CollideCircle.cpp +++ b/src/libraries/Box2D/Collision/b2_collide_circle.cpp @@ -1,24 +1,28 @@ -/* -* 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. -*/ +// MIT License -#include -#include -#include +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_collision.h" +#include "box2d/b2_circle_shape.h" +#include "box2d/b2_polygon_shape.h" void b2CollideCircles( b2Manifold* manifold, @@ -31,9 +35,9 @@ void b2CollideCircles( 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; + float distSqr = b2Dot(d, d); + float rA = circleA->m_radius, rB = circleB->m_radius; + float radius = rA + rB; if (distSqr > radius * radius) { return; @@ -61,15 +65,15 @@ void b2CollidePolygonAndCircle( // Find the min separating edge. int32 normalIndex = 0; - float32 separation = -b2_maxFloat; - float32 radius = polygonA->m_radius + circleB->m_radius; + float separation = -b2_maxFloat; + float 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]); + float s = b2Dot(normals[i], cLocal - vertices[i]); if (s > radius) { @@ -103,8 +107,8 @@ void b2CollidePolygonAndCircle( } // Compute barycentric coordinates - float32 u1 = b2Dot(cLocal - v1, v2 - v1); - float32 u2 = b2Dot(cLocal - v2, v1 - v2); + float u1 = b2Dot(cLocal - v1, v2 - v1); + float u2 = b2Dot(cLocal - v2, v1 - v2); if (u1 <= 0.0f) { if (b2DistanceSquared(cLocal, v1) > radius * radius) @@ -138,8 +142,8 @@ void b2CollidePolygonAndCircle( else { b2Vec2 faceCenter = 0.5f * (v1 + v2); - float32 separation = b2Dot(cLocal - faceCenter, normals[vertIndex1]); - if (separation > radius) + float s = b2Dot(cLocal - faceCenter, normals[vertIndex1]); + if (s > radius) { return; } diff --git a/src/libraries/Box2D/Collision/b2_collide_edge.cpp b/src/libraries/Box2D/Collision/b2_collide_edge.cpp new file mode 100644 index 000000000..e06b90097 --- /dev/null +++ b/src/libraries/Box2D/Collision/b2_collide_edge.cpp @@ -0,0 +1,524 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_collision.h" +#include "box2d/b2_circle_shape.h" +#include "box2d/b2_edge_shape.h" +#include "box2d/b2_polygon_shape.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; + + // Normal points to the right for a CCW winding + b2Vec2 n(e.y, -e.x); + float offset = b2Dot(n, Q - A); + + bool oneSided = edgeA->m_oneSided; + if (oneSided && offset < 0.0f) + { + return; + } + + // Barycentric coordinates + float u = b2Dot(e, B - Q); + float v = b2Dot(e, Q - A); + + float 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; + float dd = b2Dot(d, d); + if (dd > radius * radius) + { + return; + } + + // Is there an edge connected to A? + if (edgeA->m_oneSided) + { + b2Vec2 A1 = edgeA->m_vertex0; + b2Vec2 B1 = A; + b2Vec2 e1 = B1 - A1; + float 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; + float dd = b2Dot(d, d); + if (dd > radius * radius) + { + return; + } + + // Is there an edge connected to B? + if (edgeA->m_oneSided) + { + b2Vec2 B2 = edgeA->m_vertex3; + b2Vec2 A2 = B; + b2Vec2 e2 = B2 - A2; + float 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 + float den = b2Dot(e, e); + b2Assert(den > 0.0f); + b2Vec2 P = (1.0f / den) * (u * A + v * B); + b2Vec2 d = Q - P; + float dd = b2Dot(d, d); + if (dd > radius * radius) + { + return; + } + + if (offset < 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 + }; + + b2Vec2 normal; + Type type; + int32 index; + float 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; + float sideOffset1; + + b2Vec2 sideNormal2; + float sideOffset2; +}; + +static b2EPAxis b2ComputeEdgeSeparation(const b2TempPolygon& polygonB, const b2Vec2& v1, const b2Vec2& normal1) +{ + b2EPAxis axis; + axis.type = b2EPAxis::e_edgeA; + axis.index = -1; + axis.separation = -FLT_MAX; + axis.normal.SetZero(); + + b2Vec2 axes[2] = { normal1, -normal1 }; + + // Find axis with least overlap (min-max problem) + for (int32 j = 0; j < 2; ++j) + { + float sj = FLT_MAX; + + // Find deepest polygon vertex along axis j + for (int32 i = 0; i < polygonB.count; ++i) + { + float si = b2Dot(axes[j], polygonB.vertices[i] - v1); + if (si < sj) + { + sj = si; + } + } + + if (sj > axis.separation) + { + axis.index = j; + axis.separation = sj; + axis.normal = axes[j]; + } + } + + return axis; +} + +static b2EPAxis b2ComputePolygonSeparation(const b2TempPolygon& polygonB, const b2Vec2& v1, const b2Vec2& v2) +{ + b2EPAxis axis; + axis.type = b2EPAxis::e_unknown; + axis.index = -1; + axis.separation = -FLT_MAX; + axis.normal.SetZero(); + + for (int32 i = 0; i < polygonB.count; ++i) + { + b2Vec2 n = -polygonB.normals[i]; + + float s1 = b2Dot(n, polygonB.vertices[i] - v1); + float s2 = b2Dot(n, polygonB.vertices[i] - v2); + float s = b2Min(s1, s2); + + if (s > axis.separation) + { + axis.type = b2EPAxis::e_edgeB; + axis.index = i; + axis.separation = s; + axis.normal = n; + } + } + + return axis; +} + +void b2CollideEdgeAndPolygon(b2Manifold* manifold, + const b2EdgeShape* edgeA, const b2Transform& xfA, + const b2PolygonShape* polygonB, const b2Transform& xfB) +{ + manifold->pointCount = 0; + + b2Transform xf = b2MulT(xfA, xfB); + + b2Vec2 centroidB = b2Mul(xf, polygonB->m_centroid); + + b2Vec2 v1 = edgeA->m_vertex1; + b2Vec2 v2 = edgeA->m_vertex2; + + b2Vec2 edge1 = v2 - v1; + edge1.Normalize(); + + // Normal points to the right for a CCW winding + b2Vec2 normal1(edge1.y, -edge1.x); + float offset1 = b2Dot(normal1, centroidB - v1); + + bool oneSided = edgeA->m_oneSided; + if (oneSided && offset1 < 0.0f) + { + return; + } + + // Get polygonB in frameA + b2TempPolygon tempPolygonB; + tempPolygonB.count = polygonB->m_count; + for (int32 i = 0; i < polygonB->m_count; ++i) + { + tempPolygonB.vertices[i] = b2Mul(xf, polygonB->m_vertices[i]); + tempPolygonB.normals[i] = b2Mul(xf.q, polygonB->m_normals[i]); + } + + float radius = polygonB->m_radius + edgeA->m_radius; + + b2EPAxis edgeAxis = b2ComputeEdgeSeparation(tempPolygonB, v1, normal1); + if (edgeAxis.separation > radius) + { + return; + } + + b2EPAxis polygonAxis = b2ComputePolygonSeparation(tempPolygonB, v1, v2); + if (polygonAxis.separation > radius) + { + return; + } + + // Use hysteresis for jitter reduction. + const float k_relativeTol = 0.98f; + const float k_absoluteTol = 0.001f; + + b2EPAxis primaryAxis; + if (polygonAxis.separation - radius > k_relativeTol * (edgeAxis.separation - radius) + k_absoluteTol) + { + primaryAxis = polygonAxis; + } + else + { + primaryAxis = edgeAxis; + } + + if (oneSided) + { + // Smooth collision + // See https://box2d.org/posts/2020/06/ghost-collisions/ + + b2Vec2 edge0 = v1 - edgeA->m_vertex0; + edge0.Normalize(); + b2Vec2 normal0(edge0.y, -edge0.x); + bool convex1 = b2Cross(edge0, edge1) >= 0.0f; + + b2Vec2 edge2 = edgeA->m_vertex3 - v2; + edge2.Normalize(); + b2Vec2 normal2(edge2.y, -edge2.x); + bool convex2 = b2Cross(edge1, edge2) >= 0.0f; + + const float sinTol = 0.1f; + bool side1 = b2Dot(primaryAxis.normal, edge1) <= 0.0f; + + // Check Gauss Map + if (side1) + { + if (convex1) + { + if (b2Cross(primaryAxis.normal, normal0) > sinTol) + { + // Skip region + return; + } + + // Admit region + } + else + { + // Snap region + primaryAxis = edgeAxis; + } + } + else + { + if (convex2) + { + if (b2Cross(normal2, primaryAxis.normal) > sinTol) + { + // Skip region + return; + } + + // Admit region + } + else + { + // Snap region + primaryAxis = edgeAxis; + } + } + } + + b2ClipVertex clipPoints[2]; + b2ReferenceFace ref; + 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; + float bestValue = b2Dot(primaryAxis.normal, tempPolygonB.normals[0]); + for (int32 i = 1; i < tempPolygonB.count; ++i) + { + float value = b2Dot(primaryAxis.normal, tempPolygonB.normals[i]); + if (value < bestValue) + { + bestValue = value; + bestIndex = i; + } + } + + int32 i1 = bestIndex; + int32 i2 = i1 + 1 < tempPolygonB.count ? i1 + 1 : 0; + + clipPoints[0].v = tempPolygonB.vertices[i1]; + clipPoints[0].id.cf.indexA = 0; + clipPoints[0].id.cf.indexB = static_cast(i1); + clipPoints[0].id.cf.typeA = b2ContactFeature::e_face; + clipPoints[0].id.cf.typeB = b2ContactFeature::e_vertex; + + clipPoints[1].v = tempPolygonB.vertices[i2]; + clipPoints[1].id.cf.indexA = 0; + clipPoints[1].id.cf.indexB = static_cast(i2); + clipPoints[1].id.cf.typeA = b2ContactFeature::e_face; + clipPoints[1].id.cf.typeB = b2ContactFeature::e_vertex; + + ref.i1 = 0; + ref.i2 = 1; + ref.v1 = v1; + ref.v2 = v2; + ref.normal = primaryAxis.normal; + ref.sideNormal1 = -edge1; + ref.sideNormal2 = edge1; + } + else + { + manifold->type = b2Manifold::e_faceB; + + clipPoints[0].v = v2; + clipPoints[0].id.cf.indexA = 1; + clipPoints[0].id.cf.indexB = static_cast(primaryAxis.index); + clipPoints[0].id.cf.typeA = b2ContactFeature::e_vertex; + clipPoints[0].id.cf.typeB = b2ContactFeature::e_face; + + clipPoints[1].v = v1; + clipPoints[1].id.cf.indexA = 0; + clipPoints[1].id.cf.indexB = static_cast(primaryAxis.index); + clipPoints[1].id.cf.typeA = b2ContactFeature::e_vertex; + clipPoints[1].id.cf.typeB = b2ContactFeature::e_face; + + ref.i1 = primaryAxis.index; + ref.i2 = ref.i1 + 1 < tempPolygonB.count ? ref.i1 + 1 : 0; + ref.v1 = tempPolygonB.vertices[ref.i1]; + ref.v2 = tempPolygonB.vertices[ref.i2]; + ref.normal = tempPolygonB.normals[ref.i1]; + + // CCW winding + ref.sideNormal1.Set(ref.normal.y, -ref.normal.x); + ref.sideNormal2 = -ref.sideNormal1; + } + + ref.sideOffset1 = b2Dot(ref.sideNormal1, ref.v1); + ref.sideOffset2 = b2Dot(ref.sideNormal2, ref.v2); + + // Clip incident edge against reference face side planes + b2ClipVertex clipPoints1[2]; + b2ClipVertex clipPoints2[2]; + int32 np; + + // Clip to side 1 + np = b2ClipSegmentToLine(clipPoints1, clipPoints, ref.sideNormal1, ref.sideOffset1, ref.i1); + + if (np < b2_maxManifoldPoints) + { + return; + } + + // Clip to side 2 + np = b2ClipSegmentToLine(clipPoints2, clipPoints1, ref.sideNormal2, ref.sideOffset2, ref.i2); + + if (np < b2_maxManifoldPoints) + { + return; + } + + // Now clipPoints2 contains the clipped points. + if (primaryAxis.type == b2EPAxis::e_edgeA) + { + manifold->localNormal = ref.normal; + manifold->localPoint = ref.v1; + } + else + { + manifold->localNormal = polygonB->m_normals[ref.i1]; + manifold->localPoint = polygonB->m_vertices[ref.i1]; + } + + int32 pointCount = 0; + for (int32 i = 0; i < b2_maxManifoldPoints; ++i) + { + float separation; + + separation = b2Dot(ref.normal, clipPoints2[i].v - ref.v1); + + if (separation <= radius) + { + b2ManifoldPoint* cp = manifold->points + pointCount; + + if (primaryAxis.type == b2EPAxis::e_edgeA) + { + cp->localPoint = b2MulT(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; +} diff --git a/src/libraries/Box2D/Collision/b2CollidePolygon.cpp b/src/libraries/Box2D/Collision/b2_collide_polygon.cpp similarity index 72% rename from src/libraries/Box2D/Collision/b2CollidePolygon.cpp rename to src/libraries/Box2D/Collision/b2_collide_polygon.cpp index 0aac38b2a..f3fa850bc 100644 --- a/src/libraries/Box2D/Collision/b2CollidePolygon.cpp +++ b/src/libraries/Box2D/Collision/b2_collide_polygon.cpp @@ -1,26 +1,30 @@ -/* -* 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. -*/ +// MIT License -#include -#include +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_collision.h" +#include "box2d/b2_polygon_shape.h" // Find the max separation between poly1 and poly2 using edge normals from poly1. -static float32 b2FindMaxSeparation(int32* edgeIndex, +static float b2FindMaxSeparation(int32* edgeIndex, const b2PolygonShape* poly1, const b2Transform& xf1, const b2PolygonShape* poly2, const b2Transform& xf2) { @@ -32,7 +36,7 @@ static float32 b2FindMaxSeparation(int32* edgeIndex, b2Transform xf = b2MulT(xf2, xf1); int32 bestIndex = 0; - float32 maxSeparation = -b2_maxFloat; + float maxSeparation = -b2_maxFloat; for (int32 i = 0; i < count1; ++i) { // Get poly1 normal in frame2. @@ -40,10 +44,10 @@ static float32 b2FindMaxSeparation(int32* edgeIndex, b2Vec2 v1 = b2Mul(xf, v1s[i]); // Find deepest point for normal i. - float32 si = b2_maxFloat; + float si = b2_maxFloat; for (int32 j = 0; j < count2; ++j) { - float32 sij = b2Dot(n, v2s[j] - v1); + float sij = b2Dot(n, v2s[j] - v1); if (sij < si) { si = sij; @@ -78,10 +82,10 @@ static void b2FindIncidentEdge(b2ClipVertex c[2], // Find the incident edge on poly2. int32 index = 0; - float32 minDot = b2_maxFloat; + float minDot = b2_maxFloat; for (int32 i = 0; i < count2; ++i) { - float32 dot = b2Dot(normal1, normals2[i]); + float dot = b2Dot(normal1, normals2[i]); if (dot < minDot) { minDot = dot; @@ -118,15 +122,15 @@ void b2CollidePolygons(b2Manifold* manifold, const b2PolygonShape* polyB, const b2Transform& xfB) { manifold->pointCount = 0; - float32 totalRadius = polyA->m_radius + polyB->m_radius; + float totalRadius = polyA->m_radius + polyB->m_radius; int32 edgeA = 0; - float32 separationA = b2FindMaxSeparation(&edgeA, polyA, xfA, polyB, xfB); + float separationA = b2FindMaxSeparation(&edgeA, polyA, xfA, polyB, xfB); if (separationA > totalRadius) return; int32 edgeB = 0; - float32 separationB = b2FindMaxSeparation(&edgeB, polyB, xfB, polyA, xfA); + float separationB = b2FindMaxSeparation(&edgeB, polyB, xfB, polyA, xfA); if (separationB > totalRadius) return; @@ -135,7 +139,7 @@ void b2CollidePolygons(b2Manifold* manifold, b2Transform xf1, xf2; int32 edge1; // reference edge uint8 flip; - const float32 k_tol = 0.1f * b2_linearSlop; + const float k_tol = 0.1f * b2_linearSlop; if (separationB > separationA + k_tol) { @@ -183,11 +187,11 @@ void b2CollidePolygons(b2Manifold* manifold, v12 = b2Mul(xf1, v12); // Face offset. - float32 frontOffset = b2Dot(normal, v11); + float frontOffset = b2Dot(normal, v11); // Side offsets, extended by polytope skin thickness. - float32 sideOffset1 = -b2Dot(tangent, v11) + totalRadius; - float32 sideOffset2 = b2Dot(tangent, v12) + totalRadius; + float sideOffset1 = -b2Dot(tangent, v11) + totalRadius; + float sideOffset2 = b2Dot(tangent, v12) + totalRadius; // Clip incident edge against extruded edge1 side edges. b2ClipVertex clipPoints1[2]; @@ -215,7 +219,7 @@ void b2CollidePolygons(b2Manifold* manifold, int32 pointCount = 0; for (int32 i = 0; i < b2_maxManifoldPoints; ++i) { - float32 separation = b2Dot(normal, clipPoints2[i].v) - frontOffset; + float separation = b2Dot(normal, clipPoints2[i].v) - frontOffset; if (separation <= totalRadius) { diff --git a/src/libraries/Box2D/Collision/b2Collision.cpp b/src/libraries/Box2D/Collision/b2_collision.cpp similarity index 67% rename from src/libraries/Box2D/Collision/b2Collision.cpp rename to src/libraries/Box2D/Collision/b2_collision.cpp index 4ebf35565..8a0501be3 100644 --- a/src/libraries/Box2D/Collision/b2Collision.cpp +++ b/src/libraries/Box2D/Collision/b2_collision.cpp @@ -1,27 +1,31 @@ -/* -* 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. -*/ +// MIT License -#include -#include +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_collision.h" +#include "box2d/b2_distance.h" void b2WorldManifold::Initialize(const b2Manifold* manifold, - const b2Transform& xfA, float32 radiusA, - const b2Transform& xfB, float32 radiusB) + const b2Transform& xfA, float radiusA, + const b2Transform& xfB, float radiusB) { if (manifold->pointCount == 0) { @@ -132,8 +136,8 @@ void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState st // From Real-time Collision Detection, p179. bool b2AABB::RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const { - float32 tmin = -b2_maxFloat; - float32 tmax = b2_maxFloat; + float tmin = -b2_maxFloat; + float tmax = b2_maxFloat; b2Vec2 p = input.p1; b2Vec2 d = input.p2 - input.p1; @@ -153,12 +157,12 @@ bool b2AABB::RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const } else { - float32 inv_d = 1.0f / d(i); - float32 t1 = (lowerBound(i) - p(i)) * inv_d; - float32 t2 = (upperBound(i) - p(i)) * inv_d; + float inv_d = 1.0f / d(i); + float t1 = (lowerBound(i) - p(i)) * inv_d; + float t2 = (upperBound(i) - p(i)) * inv_d; // Sign of the normal vector. - float32 s = -1.0f; + float s = -1.0f; if (t1 > t2) { @@ -199,35 +203,37 @@ bool b2AABB::RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const // Sutherland-Hodgman clipping. int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2], - const b2Vec2& normal, float32 offset, int32 vertexIndexA) + const b2Vec2& normal, float offset, int32 vertexIndexA) { // Start with no output points - int32 numOut = 0; + int32 count = 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; + float distance0 = b2Dot(normal, vIn[0].v) - offset; + float 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 (distance0 <= 0.0f) vOut[count++] = vIn[0]; + if (distance1 <= 0.0f) vOut[count++] = 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); + float interp = distance0 / (distance0 - distance1); + vOut[count].v = vIn[0].v + interp * (vIn[1].v - vIn[0].v); // VertexA is hitting edgeB. - vOut[numOut].id.cf.indexA = static_cast(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; + vOut[count].id.cf.indexA = static_cast(vertexIndexA); + vOut[count].id.cf.indexB = vIn[0].id.cf.indexB; + vOut[count].id.cf.typeA = b2ContactFeature::e_vertex; + vOut[count].id.cf.typeB = b2ContactFeature::e_face; + ++count; + + b2Assert(count == 2); } - return numOut; + return count; } bool b2TestOverlap( const b2Shape* shapeA, int32 indexA, diff --git a/src/libraries/Box2D/Collision/b2Distance.cpp b/src/libraries/Box2D/Collision/b2_distance.cpp similarity index 64% rename from src/libraries/Box2D/Collision/b2Distance.cpp rename to src/libraries/Box2D/Collision/b2_distance.cpp index 78daab3e2..e2a27abd0 100644 --- a/src/libraries/Box2D/Collision/b2Distance.cpp +++ b/src/libraries/Box2D/Collision/b2_distance.cpp @@ -1,26 +1,30 @@ -/* -* 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. -*/ +// MIT License -#include -#include -#include -#include -#include +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_circle_shape.h" +#include "box2d/b2_distance.h" +#include "box2d/b2_edge_shape.h" +#include "box2d/b2_chain_shape.h" +#include "box2d/b2_polygon_shape.h" // GJK using Voronoi regions (Christer Ericson) and Barycentric coordinates. int32 b2_gjkCalls, b2_gjkIters, b2_gjkMaxIters; @@ -82,13 +86,19 @@ void b2DistanceProxy::Set(const b2Shape* shape, int32 index) } } +void b2DistanceProxy::Set(const b2Vec2* vertices, int32 count, float 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 + float a; // barycentric coordinate for closest point int32 indexA; // wA index int32 indexB; // wB index }; @@ -121,8 +131,8 @@ struct b2Simplex // old metric then flush the simplex. if (m_count > 1) { - float32 metric1 = cache->metric; - float32 metric2 = GetMetric(); + float metric1 = cache->metric; + float metric2 = GetMetric(); if (metric2 < 0.5f * metric1 || 2.0f * metric1 < metric2 || metric2 < b2_epsilon) { // Reset the simplex. @@ -168,7 +178,7 @@ struct b2Simplex case 2: { b2Vec2 e12 = m_v2.w - m_v1.w; - float32 sgn = b2Cross(e12, -m_v1.w); + float sgn = b2Cross(e12, -m_v1.w); if (sgn > 0.0f) { // Origin is left of e12. @@ -239,7 +249,7 @@ struct b2Simplex } } - float32 GetMetric() const + float GetMetric() const { switch (m_count) { @@ -300,7 +310,7 @@ void b2Simplex::Solve2() b2Vec2 e12 = w2 - w1; // w1 region - float32 d12_2 = -b2Dot(w1, e12); + float d12_2 = -b2Dot(w1, e12); if (d12_2 <= 0.0f) { // a2 <= 0, so we clamp it to 0 @@ -310,7 +320,7 @@ void b2Simplex::Solve2() } // w2 region - float32 d12_1 = b2Dot(w2, e12); + float d12_1 = b2Dot(w2, e12); if (d12_1 <= 0.0f) { // a1 <= 0, so we clamp it to 0 @@ -321,7 +331,7 @@ void b2Simplex::Solve2() } // Must be in e12 region. - float32 inv_d12 = 1.0f / (d12_1 + d12_2); + float 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; @@ -343,37 +353,37 @@ void b2Simplex::Solve3() // [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; + float w1e12 = b2Dot(w1, e12); + float w2e12 = b2Dot(w2, e12); + float d12_1 = w2e12; + float 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; + float w1e13 = b2Dot(w1, e13); + float w3e13 = b2Dot(w3, e13); + float d13_1 = w3e13; + float 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; + float w2e23 = b2Dot(w2, e23); + float w3e23 = b2Dot(w3, e23); + float d23_1 = w3e23; + float d23_2 = -w2e23; // Triangle123 - float32 n123 = b2Cross(e12, e13); + float 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); + float d123_1 = n123 * b2Cross(w2, w3); + float d123_2 = n123 * b2Cross(w3, w1); + float d123_3 = n123 * b2Cross(w1, w2); // w1 region if (d12_2 <= 0.0f && d13_2 <= 0.0f) @@ -386,7 +396,7 @@ void b2Simplex::Solve3() // e12 if (d12_1 > 0.0f && d12_2 > 0.0f && d123_3 <= 0.0f) { - float32 inv_d12 = 1.0f / (d12_1 + d12_2); + float 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; @@ -396,7 +406,7 @@ void b2Simplex::Solve3() // e13 if (d13_1 > 0.0f && d13_2 > 0.0f && d123_2 <= 0.0f) { - float32 inv_d13 = 1.0f / (d13_1 + d13_2); + float 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; @@ -425,7 +435,7 @@ void b2Simplex::Solve3() // e23 if (d23_1 > 0.0f && d23_2 > 0.0f && d123_1 <= 0.0f) { - float32 inv_d23 = 1.0f / (d23_1 + d23_2); + float 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; @@ -434,7 +444,7 @@ void b2Simplex::Solve3() } // Must be in triangle123 - float32 inv_d123 = 1.0f / (d123_1 + d123_2 + d123_3); + float 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; @@ -466,9 +476,6 @@ void b2Distance(b2DistanceOutput* output, int32 saveA[3], saveB[3]; int32 saveCount = 0; - float32 distanceSqr1 = b2_maxFloat; - float32 distanceSqr2 = distanceSqr1; - // Main iteration loop. int32 iter = 0; while (iter < k_maxIters) @@ -504,17 +511,6 @@ void b2Distance(b2DistanceOutput* output, break; } - // Compute closest point. - b2Vec2 p = simplex.GetClosestPoint(); - distanceSqr2 = p.LengthSquared(); - - // Ensure progress - if (distanceSqr2 >= distanceSqr1) - { - //break; - } - distanceSqr1 = distanceSqr2; - // Get search direction. b2Vec2 d = simplex.GetSearchDirection(); @@ -534,7 +530,6 @@ void b2Distance(b2DistanceOutput* output, 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; @@ -577,8 +572,8 @@ void b2Distance(b2DistanceOutput* output, // Apply radii if requested. if (input->useRadii) { - float32 rA = proxyA->m_radius; - float32 rB = proxyB->m_radius; + float rA = proxyA->m_radius; + float rB = proxyB->m_radius; if (output->distance > rA + rB && output->distance > b2_epsilon) { @@ -601,3 +596,151 @@ void b2Distance(b2DistanceOutput* output, } } } + +// 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; + + float radiusA = b2Max(proxyA->m_radius, b2_polygonRadius); + float radiusB = b2Max(proxyB->m_radius, b2_polygonRadius); + float radius = radiusA + radiusB; + + b2Transform xfA = input->transformA; + b2Transform xfB = input->transformB; + + b2Vec2 r = input->translationB; + b2Vec2 n(0.0f, 0.0f); + float 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 + float sigma = b2Max(b2_polygonRadius, radius - b2_polygonRadius); + const float tolerance = 0.5f * b2_linearSlop; + + // Main iteration loop. + const int32 k_maxIters = 20; + int32 iter = 0; + while (iter < k_maxIters && 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 + float vp = b2Dot(v, p); + float 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; + } + + if (iter == 0) + { + // Initial overlap + return false; + } + + // 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/libraries/Box2D/Collision/b2DynamicTree.cpp b/src/libraries/Box2D/Collision/b2_dynamic_tree.cpp similarity index 83% rename from src/libraries/Box2D/Collision/b2DynamicTree.cpp rename to src/libraries/Box2D/Collision/b2_dynamic_tree.cpp index ef57b4220..45e093320 100644 --- a/src/libraries/Box2D/Collision/b2DynamicTree.cpp +++ b/src/libraries/Box2D/Collision/b2_dynamic_tree.cpp @@ -1,22 +1,25 @@ -/* -* 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. -*/ +// MIT License -#include +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. +#include "box2d/b2_dynamic_tree.h" #include b2DynamicTree::b2DynamicTree() @@ -83,7 +86,8 @@ int32 b2DynamicTree::AllocateNode() m_nodes[nodeId].child1 = b2_nullNode; m_nodes[nodeId].child2 = b2_nullNode; m_nodes[nodeId].height = 0; - m_nodes[nodeId].userData = NULL; + m_nodes[nodeId].userData = nullptr; + m_nodes[nodeId].moved = false; ++m_nodeCount; return nodeId; } @@ -112,6 +116,7 @@ int32 b2DynamicTree::CreateProxy(const b2AABB& aabb, void* userData) m_nodes[proxyId].aabb.upperBound = aabb.upperBound + r; m_nodes[proxyId].userData = userData; m_nodes[proxyId].height = 0; + m_nodes[proxyId].moved = true; InsertLeaf(proxyId); @@ -133,43 +138,61 @@ bool b2DynamicTree::MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& d b2Assert(m_nodes[proxyId].IsLeaf()); - if (m_nodes[proxyId].aabb.Contains(aabb)) - { - return false; - } - - RemoveLeaf(proxyId); - - // Extend AABB. - b2AABB b = aabb; + // Extend AABB + b2AABB fatAABB; b2Vec2 r(b2_aabbExtension, b2_aabbExtension); - b.lowerBound = b.lowerBound - r; - b.upperBound = b.upperBound + r; + fatAABB.lowerBound = aabb.lowerBound - r; + fatAABB.upperBound = aabb.upperBound + r; - // Predict AABB displacement. + // Predict AABB movement b2Vec2 d = b2_aabbMultiplier * displacement; if (d.x < 0.0f) { - b.lowerBound.x += d.x; + fatAABB.lowerBound.x += d.x; } else { - b.upperBound.x += d.x; + fatAABB.upperBound.x += d.x; } if (d.y < 0.0f) { - b.lowerBound.y += d.y; + fatAABB.lowerBound.y += d.y; } else { - b.upperBound.y += d.y; + fatAABB.upperBound.y += d.y; } - m_nodes[proxyId].aabb = b; + const b2AABB& treeAABB = m_nodes[proxyId].aabb; + if (treeAABB.Contains(aabb)) + { + // The tree AABB still contains the object, but it might be too large. + // Perhaps the object was moving fast but has since gone to sleep. + // The huge AABB is larger than the new fat AABB. + b2AABB hugeAABB; + hugeAABB.lowerBound = fatAABB.lowerBound - 4.0f * r; + hugeAABB.upperBound = fatAABB.upperBound + 4.0f * r; + + if (hugeAABB.Contains(treeAABB)) + { + // The tree AABB contains the object AABB and the tree AABB is + // not too large. No tree update needed. + return false; + } + + // Otherwise the tree AABB is huge and needs to be shrunk + } + + RemoveLeaf(proxyId); + + m_nodes[proxyId].aabb = fatAABB; InsertLeaf(proxyId); + + m_nodes[proxyId].moved = true; + return true; } @@ -192,20 +215,20 @@ void b2DynamicTree::InsertLeaf(int32 leaf) int32 child1 = m_nodes[index].child1; int32 child2 = m_nodes[index].child2; - float32 area = m_nodes[index].aabb.GetPerimeter(); + float area = m_nodes[index].aabb.GetPerimeter(); b2AABB combinedAABB; combinedAABB.Combine(m_nodes[index].aabb, leafAABB); - float32 combinedArea = combinedAABB.GetPerimeter(); + float combinedArea = combinedAABB.GetPerimeter(); // Cost of creating a new parent for this node and the new leaf - float32 cost = 2.0f * combinedArea; + float cost = 2.0f * combinedArea; // Minimum cost of pushing the leaf further down the tree - float32 inheritanceCost = 2.0f * (combinedArea - area); + float inheritanceCost = 2.0f * (combinedArea - area); // Cost of descending into child1 - float32 cost1; + float cost1; if (m_nodes[child1].IsLeaf()) { b2AABB aabb; @@ -216,13 +239,13 @@ void b2DynamicTree::InsertLeaf(int32 leaf) { b2AABB aabb; aabb.Combine(leafAABB, m_nodes[child1].aabb); - float32 oldArea = m_nodes[child1].aabb.GetPerimeter(); - float32 newArea = aabb.GetPerimeter(); + float oldArea = m_nodes[child1].aabb.GetPerimeter(); + float newArea = aabb.GetPerimeter(); cost1 = (newArea - oldArea) + inheritanceCost; } // Cost of descending into child2 - float32 cost2; + float cost2; if (m_nodes[child2].IsLeaf()) { b2AABB aabb; @@ -233,8 +256,8 @@ void b2DynamicTree::InsertLeaf(int32 leaf) { b2AABB aabb; aabb.Combine(leafAABB, m_nodes[child2].aabb); - float32 oldArea = m_nodes[child2].aabb.GetPerimeter(); - float32 newArea = aabb.GetPerimeter(); + float oldArea = m_nodes[child2].aabb.GetPerimeter(); + float newArea = aabb.GetPerimeter(); cost2 = newArea - oldArea + inheritanceCost; } @@ -261,7 +284,7 @@ void b2DynamicTree::InsertLeaf(int32 leaf) int32 oldParent = m_nodes[sibling].parent; int32 newParent = AllocateNode(); m_nodes[newParent].parent = oldParent; - m_nodes[newParent].userData = NULL; + m_nodes[newParent].userData = nullptr; m_nodes[newParent].aabb.Combine(leafAABB, m_nodes[sibling].aabb); m_nodes[newParent].height = m_nodes[sibling].height + 1; @@ -528,7 +551,7 @@ int32 b2DynamicTree::GetHeight() const } // -float32 b2DynamicTree::GetAreaRatio() const +float b2DynamicTree::GetAreaRatio() const { if (m_root == b2_nullNode) { @@ -536,9 +559,9 @@ float32 b2DynamicTree::GetAreaRatio() const } const b2TreeNode* root = m_nodes + m_root; - float32 rootArea = root->aabb.GetPerimeter(); + float rootArea = root->aabb.GetPerimeter(); - float32 totalArea = 0.0f; + float totalArea = 0.0f; for (int32 i = 0; i < m_nodeCapacity; ++i) { const b2TreeNode* node = m_nodes + i; @@ -652,6 +675,7 @@ void b2DynamicTree::ValidateMetrics(int32 index) const void b2DynamicTree::Validate() const { +#if defined(b2DEBUG) ValidateStructure(m_root); ValidateMetrics(m_root); @@ -667,6 +691,7 @@ void b2DynamicTree::Validate() const b2Assert(GetHeight() == ComputeHeight()); b2Assert(m_nodeCount + freeCount == m_nodeCapacity); +#endif } int32 b2DynamicTree::GetMaxBalance() const @@ -719,7 +744,7 @@ void b2DynamicTree::RebuildBottomUp() while (count > 1) { - float32 minCost = b2_maxFloat; + float minCost = b2_maxFloat; int32 iMin = -1, jMin = -1; for (int32 i = 0; i < count; ++i) { @@ -730,7 +755,7 @@ void b2DynamicTree::RebuildBottomUp() b2AABB aabbj = m_nodes[nodes[j]].aabb; b2AABB b; b.Combine(aabbi, aabbj); - float32 cost = b.GetPerimeter(); + float cost = b.GetPerimeter(); if (cost < minCost) { iMin = i; diff --git a/src/libraries/Box2D/Collision/Shapes/b2EdgeShape.cpp b/src/libraries/Box2D/Collision/b2_edge_shape.cpp similarity index 52% rename from src/libraries/Box2D/Collision/Shapes/b2EdgeShape.cpp rename to src/libraries/Box2D/Collision/b2_edge_shape.cpp index 8bcd12f7a..65f0606a6 100644 --- a/src/libraries/Box2D/Collision/Shapes/b2EdgeShape.cpp +++ b/src/libraries/Box2D/Collision/b2_edge_shape.cpp @@ -1,30 +1,43 @@ -/* -* 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. -*/ +// MIT License -#include +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_edge_shape.h" +#include "box2d/b2_block_allocator.h" #include -void b2EdgeShape::Set(const b2Vec2& v1, const b2Vec2& v2) +void b2EdgeShape::SetOneSided(const b2Vec2& v0, const b2Vec2& v1, const b2Vec2& v2, const b2Vec2& v3) +{ + m_vertex0 = v0; + m_vertex1 = v1; + m_vertex2 = v2; + m_vertex3 = v3; + m_oneSided = true; +} + +void b2EdgeShape::SetTwoSided(const b2Vec2& v1, const b2Vec2& v2) { m_vertex1 = v1; m_vertex2 = v2; - m_hasVertex0 = false; - m_hasVertex3 = false; + m_oneSided = false; } b2Shape* b2EdgeShape::Clone(b2BlockAllocator* allocator) const @@ -64,21 +77,28 @@ bool b2EdgeShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input, b2Vec2 v1 = m_vertex1; b2Vec2 v2 = m_vertex2; b2Vec2 e = v2 - v1; + + // Normal points to the right, looking from v1 at v2 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); + float numerator = b2Dot(normal, v1 - p1); + if (m_oneSided && numerator > 0.0f) + { + return false; + } + + float denominator = b2Dot(normal, d); if (denominator == 0.0f) { return false; } - float32 t = numerator / denominator; + float t = numerator / denominator; if (t < 0.0f || input.maxFraction < t) { return false; @@ -89,13 +109,13 @@ bool b2EdgeShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input, // q = v1 + s * r // s = dot(q - v1, r) / dot(r, r) b2Vec2 r = v2 - v1; - float32 rr = b2Dot(r, r); + float rr = b2Dot(r, r); if (rr == 0.0f) { return false; } - float32 s = b2Dot(q - v1, r) / rr; + float s = b2Dot(q - v1, r) / rr; if (s < 0.0f || 1.0f < s) { return false; @@ -128,7 +148,7 @@ void b2EdgeShape::ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childIn aabb->upperBound = upper + r; } -void b2EdgeShape::ComputeMass(b2MassData* massData, float32 density) const +void b2EdgeShape::ComputeMass(b2MassData* massData, float density) const { B2_NOT_USED(density); diff --git a/src/libraries/Box2D/Collision/Shapes/b2PolygonShape.cpp b/src/libraries/Box2D/Collision/b2_polygon_shape.cpp similarity index 74% rename from src/libraries/Box2D/Collision/Shapes/b2PolygonShape.cpp rename to src/libraries/Box2D/Collision/b2_polygon_shape.cpp index 26ba7b3a7..368fb801f 100644 --- a/src/libraries/Box2D/Collision/Shapes/b2PolygonShape.cpp +++ b/src/libraries/Box2D/Collision/b2_polygon_shape.cpp @@ -1,22 +1,28 @@ -/* -* 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. -*/ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_polygon_shape.h" +#include "box2d/b2_block_allocator.h" -#include #include b2Shape* b2PolygonShape::Clone(b2BlockAllocator* allocator) const @@ -27,7 +33,7 @@ b2Shape* b2PolygonShape::Clone(b2BlockAllocator* allocator) const return clone; } -void b2PolygonShape::SetAsBox(float32 hx, float32 hy) +void b2PolygonShape::SetAsBox(float hx, float hy) { m_count = 4; m_vertices[0].Set(-hx, -hy); @@ -41,7 +47,7 @@ void b2PolygonShape::SetAsBox(float32 hx, float32 hy) m_centroid.SetZero(); } -void b2PolygonShape::SetAsBox(float32 hx, float32 hy, const b2Vec2& center, float32 angle) +void b2PolygonShape::SetAsBox(float hx, float hy, const b2Vec2& center, float angle) { m_count = 4; m_vertices[0].Set(-hx, -hy); @@ -75,36 +81,28 @@ static b2Vec2 ComputeCentroid(const b2Vec2* vs, int32 count) { b2Assert(count >= 3); - b2Vec2 c; c.Set(0.0f, 0.0f); - float32 area = 0.0f; + b2Vec2 c(0.0f, 0.0f); + float 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 + // Get a reference point for forming triangles. + // Use the first vertex to reduce round-off errors. + b2Vec2 s = vs[0]; - const float32 inv3 = 1.0f / 3.0f; + const float 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 p1 = vs[0] - s; + b2Vec2 p2 = vs[i] - s; + b2Vec2 p3 = i + 1 < count ? vs[i+1] - s : vs[0] - s; b2Vec2 e1 = p2 - p1; b2Vec2 e2 = p3 - p1; - float32 D = b2Cross(e1, e2); + float D = b2Cross(e1, e2); - float32 triangleArea = 0.5f * D; + float triangleArea = 0.5f * D; area += triangleArea; // Area weighted centroid @@ -113,7 +111,7 @@ static b2Vec2 ComputeCentroid(const b2Vec2* vs, int32 count) // Centroid b2Assert(area > b2_epsilon); - c *= 1.0f / area; + c = (1.0f / area) * c + s; return c; } @@ -165,10 +163,10 @@ void b2PolygonShape::Set(const b2Vec2* vertices, int32 count) // Find the right most point on the hull int32 i0 = 0; - float32 x0 = ps[0].x; + float x0 = ps[0].x; for (int32 i = 1; i < n; ++i) { - float32 x = ps[i].x; + float x = ps[i].x; if (x > x0 || (x == x0 && ps[i].y < ps[i0].y)) { i0 = i; @@ -182,6 +180,7 @@ void b2PolygonShape::Set(const b2Vec2* vertices, int32 count) for (;;) { + b2Assert(m < b2_maxPolygonVertices); hull[m] = ih; int32 ie = 0; @@ -195,7 +194,7 @@ void b2PolygonShape::Set(const b2Vec2* vertices, int32 count) b2Vec2 r = ps[ie] - ps[hull[m]]; b2Vec2 v = ps[j] - ps[hull[m]]; - float32 c = b2Cross(r, v); + float c = b2Cross(r, v); if (c < 0.0f) { ie = j; @@ -254,7 +253,7 @@ bool b2PolygonShape::TestPoint(const b2Transform& xf, const b2Vec2& p) const for (int32 i = 0; i < m_count; ++i) { - float32 dot = b2Dot(m_normals[i], pLocal - m_vertices[i]); + float dot = b2Dot(m_normals[i], pLocal - m_vertices[i]); if (dot > 0.0f) { return false; @@ -274,7 +273,7 @@ bool b2PolygonShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& inpu b2Vec2 p2 = b2MulT(xf.q, input.p2 - xf.p); b2Vec2 d = p2 - p1; - float32 lower = 0.0f, upper = input.maxFraction; + float lower = 0.0f, upper = input.maxFraction; int32 index = -1; @@ -283,8 +282,8 @@ bool b2PolygonShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& inpu // 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); + float numerator = b2Dot(m_normals[i], m_vertices[i] - p1); + float denominator = b2Dot(m_normals[i], d); if (denominator == 0.0f) { @@ -355,7 +354,7 @@ void b2PolygonShape::ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 chil aabb->upperBound = upper + r; } -void b2PolygonShape::ComputeMass(b2MassData* massData, float32 density) const +void b2PolygonShape::ComputeMass(b2MassData* massData, float density) const { // Polygon mass, centroid, and inertia. // Let rho be the polygon density in mass per unit area. @@ -383,22 +382,15 @@ void b2PolygonShape::ComputeMass(b2MassData* massData, float32 density) const b2Assert(m_count >= 3); - b2Vec2 center; center.Set(0.0f, 0.0f); - float32 area = 0.0f; - float32 I = 0.0f; + b2Vec2 center(0.0f, 0.0f); + float area = 0.0f; + float 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); + // Get a reference point for forming triangles. + // Use the first vertex to reduce round-off errors. + b2Vec2 s = m_vertices[0]; - // 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; + const float k_inv3 = 1.0f / 3.0f; for (int32 i = 0; i < m_count; ++i) { @@ -406,19 +398,19 @@ void b2PolygonShape::ComputeMass(b2MassData* massData, float32 density) const 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); + float D = b2Cross(e1, e2); - float32 triangleArea = 0.5f * D; + float 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; + float ex1 = e1.x, ey1 = e1.y; + float ex2 = e2.x, ey2 = e2.y; - float32 intx2 = ex1*ex1 + ex2*ex1 + ex2*ex2; - float32 inty2 = ey1*ey1 + ey2*ey1 + ey2*ey2; + float intx2 = ex1*ex1 + ex2*ex1 + ex2*ex2; + float inty2 = ey1*ey1 + ey2*ey1 + ey2*ey2; I += (0.25f * k_inv3 * D) * (intx2 + inty2); } @@ -455,7 +447,7 @@ bool b2PolygonShape::Validate() const } b2Vec2 v = m_vertices[j] - p; - float32 c = b2Cross(e, v); + float c = b2Cross(e, v); if (c < 0.0f) { return false; diff --git a/src/libraries/Box2D/Collision/b2TimeOfImpact.cpp b/src/libraries/Box2D/Collision/b2_time_of_impact.cpp similarity index 78% rename from src/libraries/Box2D/Collision/b2TimeOfImpact.cpp rename to src/libraries/Box2D/Collision/b2_time_of_impact.cpp index 60da95c38..ca61a31f7 100644 --- a/src/libraries/Box2D/Collision/b2TimeOfImpact.cpp +++ b/src/libraries/Box2D/Collision/b2_time_of_impact.cpp @@ -1,31 +1,35 @@ -/* -* 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. -*/ +// MIT License -#include -#include -#include -#include -#include -#include +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_collision.h" +#include "box2d/b2_distance.h" +#include "box2d/b2_circle_shape.h" +#include "box2d/b2_polygon_shape.h" +#include "box2d/b2_time_of_impact.h" +#include "box2d/b2_timer.h" #include -float32 b2_toiTime, b2_toiMaxTime; +float b2_toiTime, b2_toiMaxTime; int32 b2_toiCalls, b2_toiIters, b2_toiMaxIters; int32 b2_toiRootIters, b2_toiMaxRootIters; @@ -41,10 +45,10 @@ struct b2SeparationFunction // TODO_ERIN might not need to return the separation - float32 Initialize(const b2SimplexCache* cache, + float Initialize(const b2SimplexCache* cache, const b2DistanceProxy* proxyA, const b2Sweep& sweepA, const b2DistanceProxy* proxyB, const b2Sweep& sweepB, - float32 t1) + float t1) { m_proxyA = proxyA; m_proxyB = proxyB; @@ -66,7 +70,7 @@ struct b2SeparationFunction b2Vec2 pointA = b2Mul(xfA, localPointA); b2Vec2 pointB = b2Mul(xfB, localPointB); m_axis = pointB - pointA; - float32 s = m_axis.Normalize(); + float s = m_axis.Normalize(); return s; } else if (cache->indexA[0] == cache->indexA[1]) @@ -86,7 +90,7 @@ struct b2SeparationFunction b2Vec2 localPointA = proxyA->GetVertex(cache->indexA[0]); b2Vec2 pointA = b2Mul(xfA, localPointA); - float32 s = b2Dot(pointA - pointB, normal); + float s = b2Dot(pointA - pointB, normal); if (s < 0.0f) { m_axis = -m_axis; @@ -111,7 +115,7 @@ struct b2SeparationFunction b2Vec2 localPointB = m_proxyB->GetVertex(cache->indexB[0]); b2Vec2 pointB = b2Mul(xfB, localPointB); - float32 s = b2Dot(pointB - pointA, normal); + float s = b2Dot(pointB - pointA, normal); if (s < 0.0f) { m_axis = -m_axis; @@ -122,7 +126,7 @@ struct b2SeparationFunction } // - float32 FindMinSeparation(int32* indexA, int32* indexB, float32 t) const + float FindMinSeparation(int32* indexA, int32* indexB, float t) const { b2Transform xfA, xfB; m_sweepA.GetTransform(&xfA, t); @@ -144,7 +148,7 @@ struct b2SeparationFunction b2Vec2 pointA = b2Mul(xfA, localPointA); b2Vec2 pointB = b2Mul(xfB, localPointB); - float32 separation = b2Dot(pointB - pointA, m_axis); + float separation = b2Dot(pointB - pointA, m_axis); return separation; } @@ -161,7 +165,7 @@ struct b2SeparationFunction b2Vec2 localPointB = m_proxyB->GetVertex(*indexB); b2Vec2 pointB = b2Mul(xfB, localPointB); - float32 separation = b2Dot(pointB - pointA, normal); + float separation = b2Dot(pointB - pointA, normal); return separation; } @@ -178,7 +182,7 @@ struct b2SeparationFunction b2Vec2 localPointA = m_proxyA->GetVertex(*indexA); b2Vec2 pointA = b2Mul(xfA, localPointA); - float32 separation = b2Dot(pointA - pointB, normal); + float separation = b2Dot(pointA - pointB, normal); return separation; } @@ -191,7 +195,7 @@ struct b2SeparationFunction } // - float32 Evaluate(int32 indexA, int32 indexB, float32 t) const + float Evaluate(int32 indexA, int32 indexB, float t) const { b2Transform xfA, xfB; m_sweepA.GetTransform(&xfA, t); @@ -206,7 +210,7 @@ struct b2SeparationFunction b2Vec2 pointA = b2Mul(xfA, localPointA); b2Vec2 pointB = b2Mul(xfB, localPointB); - float32 separation = b2Dot(pointB - pointA, m_axis); + float separation = b2Dot(pointB - pointA, m_axis); return separation; } @@ -219,7 +223,7 @@ struct b2SeparationFunction b2Vec2 localPointB = m_proxyB->GetVertex(indexB); b2Vec2 pointB = b2Mul(xfB, localPointB); - float32 separation = b2Dot(pointB - pointA, normal); + float separation = b2Dot(pointB - pointA, normal); return separation; } @@ -231,7 +235,7 @@ struct b2SeparationFunction b2Vec2 localPointA = m_proxyA->GetVertex(indexA); b2Vec2 pointA = b2Mul(xfA, localPointA); - float32 separation = b2Dot(pointA - pointB, normal); + float separation = b2Dot(pointA - pointB, normal); return separation; } @@ -271,14 +275,14 @@ void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input) sweepA.Normalize(); sweepB.Normalize(); - float32 tMax = input->tMax; + float 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; + float totalRadius = proxyA->m_radius + proxyB->m_radius; + float target = b2Max(b2_linearSlop, totalRadius - 3.0f * b2_linearSlop); + float tolerance = 0.25f * b2_linearSlop; b2Assert(target > tolerance); - float32 t1 = 0.0f; + float t1 = 0.0f; const int32 k_maxIterations = 20; // TODO_ERIN b2Settings int32 iter = 0; @@ -329,17 +333,17 @@ void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input) // 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]; + float dx = 1.0f / N; + float xs[N+1]; + float fs[N+1]; - float32 x = 0.0f; + float 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; + float f = fcn.Evaluate(xfA, xfB) - target; printf("%g %g\n", x, f); @@ -354,13 +358,13 @@ void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input) // 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; + float 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); + float s2 = fcn.FindMinSeparation(&indexA, &indexB, t2); // Is the final configuration separated? if (s2 > target + tolerance) @@ -381,7 +385,7 @@ void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input) } // Compute the initial separation of the witness points. - float32 s1 = fcn.Evaluate(indexA, indexB, t1); + float s1 = fcn.Evaluate(indexA, indexB, t1); // Check for initial overlap. This might happen if the root finder // runs out of iterations. @@ -405,11 +409,11 @@ void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input) // Compute 1D root of: f(x) - target = 0 int32 rootIterCount = 0; - float32 a1 = t1, a2 = t2; + float a1 = t1, a2 = t2; for (;;) { // Use a mix of the secant rule and bisection. - float32 t; + float t; if (rootIterCount & 1) { // Secant rule to improve convergence. @@ -424,7 +428,7 @@ void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input) ++rootIterCount; ++b2_toiRootIters; - float32 s = fcn.Evaluate(indexA, indexB, t); + float s = fcn.Evaluate(indexA, indexB, t); if (b2Abs(s - target) < tolerance) { @@ -480,7 +484,7 @@ void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input) b2_toiMaxIters = b2Max(b2_toiMaxIters, iter); - float32 time = timer.GetMilliseconds(); + float time = timer.GetMilliseconds(); b2_toiMaxTime = b2Max(b2_toiMaxTime, time); b2_toiTime += time; } diff --git a/src/libraries/Box2D/Common/b2BlockAllocator.h b/src/libraries/Box2D/Common/b2BlockAllocator.h deleted file mode 100644 index cea3cef96..000000000 --- a/src/libraries/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 - -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/libraries/Box2D/Common/b2Draw.cpp b/src/libraries/Box2D/Common/b2Draw.cpp deleted file mode 100644 index 2cd9b1a56..000000000 --- a/src/libraries/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 - -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/libraries/Box2D/Common/b2Draw.h b/src/libraries/Box2D/Common/b2Draw.h deleted file mode 100644 index be65fb0ff..000000000 --- a/src/libraries/Box2D/Common/b2Draw.h +++ /dev/null @@ -1,86 +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 - -/// Color for debug drawing. Each value has the range [0,1]. -struct b2Color -{ - b2Color() {} - b2Color(float32 r, float32 g, float32 b, float32 a = 1.0f) : r(r), g(g), b(b), a(a) {} - void Set(float32 ri, float32 gi, float32 bi, float32 ai = 1.0f) { r = ri; g = gi; b = bi; a = ai; } - 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; - -protected: - uint32 m_drawFlags; -}; - -#endif diff --git a/src/libraries/Box2D/Common/b2GrowableStack.h b/src/libraries/Box2D/Common/b2GrowableStack.h deleted file mode 100644 index 989247710..000000000 --- a/src/libraries/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 -#include - -/// 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 -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 = NULL; - } - } - - 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/libraries/Box2D/Common/b2Math.cpp b/src/libraries/Box2D/Common/b2Math.cpp deleted file mode 100644 index d6027be90..000000000 --- a/src/libraries/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 - -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/libraries/Box2D/Common/b2Settings.cpp b/src/libraries/Box2D/Common/b2Settings.cpp deleted file mode 100644 index ed6d83e0e..000000000 --- a/src/libraries/Box2D/Common/b2Settings.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 -#include -#include -#include - -#include "common/Exception.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); -} - -void loveAssert(bool test, const char *teststr) -{ - if (!test) - throw love::Exception("Box2D assertion failed: %s", teststr); -} diff --git a/src/libraries/Box2D/Common/b2StackAllocator.cpp b/src/libraries/Box2D/Common/b2StackAllocator.cpp deleted file mode 100644 index 321cabb23..000000000 --- a/src/libraries/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 -#include - -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 = NULL; -} - -int32 b2StackAllocator::GetMaxAllocation() const -{ - return m_maxAllocation; -} diff --git a/src/libraries/Box2D/Common/b2StackAllocator.h b/src/libraries/Box2D/Common/b2StackAllocator.h deleted file mode 100644 index bb87a7edc..000000000 --- a/src/libraries/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 - -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/libraries/Box2D/Common/b2Timer.cpp b/src/libraries/Box2D/Common/b2Timer.cpp deleted file mode 100644 index cbea5309e..000000000 --- a/src/libraries/Box2D/Common/b2Timer.cpp +++ /dev/null @@ -1,101 +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 - -#if defined(_WIN32) - -float64 b2Timer::s_invFrequency = 0.0f; - -#define WIN32_LEAN_AND_MEAN -#include - -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 - -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); - return 1000.0f * (t.tv_sec - m_start_sec) + 0.001f * (t.tv_usec - m_start_usec); -} - -#else - -b2Timer::b2Timer() -{ -} - -void b2Timer::Reset() -{ -} - -float32 b2Timer::GetMilliseconds() const -{ - return 0.0f; -} - -#endif diff --git a/src/libraries/Box2D/Common/b2Timer.h b/src/libraries/Box2D/Common/b2Timer.h deleted file mode 100644 index edf1ca459..000000000 --- a/src/libraries/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 - -/// 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 m_start_sec; - unsigned long m_start_usec; -#endif -}; - -#endif diff --git a/src/libraries/Box2D/Common/b2BlockAllocator.cpp b/src/libraries/Box2D/Common/b2_block_allocator.cpp similarity index 59% rename from src/libraries/Box2D/Common/b2BlockAllocator.cpp rename to src/libraries/Box2D/Common/b2_block_allocator.cpp index f16db7028..595f2ad39 100644 --- a/src/libraries/Box2D/Common/b2BlockAllocator.cpp +++ b/src/libraries/Box2D/Common/b2_block_allocator.cpp @@ -1,28 +1,36 @@ -/* -* 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. -*/ +// MIT License -#include +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_block_allocator.h" #include #include #include -#include -int32 b2BlockAllocator::s_blockSizes[b2_blockSizes] = +static const int32 b2_chunkSize = 16 * 1024; +static const int32 b2_maxBlockSize = 640; +static const int32 b2_chunkArrayIncrement = 128; + +// These are the supported object sizes. Actual allocations are rounded up the next size. +static const int32 b2_blockSizes[b2_blockSizeCount] = { 16, // 0 32, // 1 @@ -39,8 +47,33 @@ int32 b2BlockAllocator::s_blockSizes[b2_blockSizes] = 512, // 12 640, // 13 }; -uint8 b2BlockAllocator::s_blockSizeLookup[b2_maxBlockSize + 1]; -bool b2BlockAllocator::s_blockSizeLookupInitialized; + +// This maps an arbitrary allocation size to a suitable slot in b2_blockSizes. +struct b2SizeMap +{ + b2SizeMap() + { + int32 j = 0; + values[0] = 0; + for (int32 i = 1; i <= b2_maxBlockSize; ++i) + { + b2Assert(j < b2_blockSizeCount); + if (i <= b2_blockSizes[j]) + { + values[i] = (uint8)j; + } + else + { + ++j; + values[i] = (uint8)j; + } + } + } + + uint8 values[b2_maxBlockSize + 1]; +}; + +static const b2SizeMap b2_sizeMap; struct b2Chunk { @@ -55,7 +88,7 @@ struct b2Block b2BlockAllocator::b2BlockAllocator() { - b2Assert(b2_blockSizes < UCHAR_MAX); + b2Assert(b2_blockSizeCount < UCHAR_MAX); m_chunkSpace = b2_chunkArrayIncrement; m_chunkCount = 0; @@ -63,26 +96,6 @@ b2BlockAllocator::b2BlockAllocator() 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() @@ -98,7 +111,9 @@ b2BlockAllocator::~b2BlockAllocator() void* b2BlockAllocator::Allocate(int32 size) { if (size == 0) - return NULL; + { + return nullptr; + } b2Assert(0 < size); @@ -107,8 +122,8 @@ void* b2BlockAllocator::Allocate(int32 size) return b2Alloc(size); } - int32 index = s_blockSizeLookup[size]; - b2Assert(0 <= index && index < b2_blockSizes); + int32 index = b2_sizeMap.values[size]; + b2Assert(0 <= index && index < b2_blockSizeCount); if (m_freeLists[index]) { @@ -133,7 +148,7 @@ void* b2BlockAllocator::Allocate(int32 size) #if defined(_DEBUG) memset(chunk->blocks, 0xcd, b2_chunkSize); #endif - int32 blockSize = s_blockSizes[index]; + int32 blockSize = b2_blockSizes[index]; chunk->blockSize = blockSize; int32 blockCount = b2_chunkSize / blockSize; b2Assert(blockCount * blockSize <= b2_chunkSize); @@ -144,7 +159,7 @@ void* b2BlockAllocator::Allocate(int32 size) block->next = next; } b2Block* last = (b2Block*)((int8*)chunk->blocks + blockSize * (blockCount - 1)); - last->next = NULL; + last->next = nullptr; m_freeLists[index] = chunk->blocks->next; ++m_chunkCount; @@ -168,12 +183,12 @@ void b2BlockAllocator::Free(void* p, int32 size) return; } - int32 index = s_blockSizeLookup[size]; - b2Assert(0 <= index && index < b2_blockSizes); + int32 index = b2_sizeMap.values[size]; + b2Assert(0 <= index && index < b2_blockSizeCount); -#ifdef _DEBUG +#if defined(_DEBUG) // Verify the memory address and size is valid. - int32 blockSize = s_blockSizes[index]; + int32 blockSize = b2_blockSizes[index]; bool found = false; for (int32 i = 0; i < m_chunkCount; ++i) { @@ -211,6 +226,5 @@ void b2BlockAllocator::Clear() m_chunkCount = 0; memset(m_chunks, 0, m_chunkSpace * sizeof(b2Chunk)); - memset(m_freeLists, 0, sizeof(m_freeLists)); } diff --git a/src/libraries/Box2D/Common/b2_draw.cpp b/src/libraries/Box2D/Common/b2_draw.cpp new file mode 100644 index 000000000..1ec11e54a --- /dev/null +++ b/src/libraries/Box2D/Common/b2_draw.cpp @@ -0,0 +1,47 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. +#include "box2d/b2_draw.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/libraries/Box2D/Common/b2_math.cpp b/src/libraries/Box2D/Common/b2_math.cpp new file mode 100644 index 000000000..a14460cd5 --- /dev/null +++ b/src/libraries/Box2D/Common/b2_math.cpp @@ -0,0 +1,98 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_math.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 +{ + float 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 +{ + float a11 = ex.x, a12 = ey.x, a21 = ex.y, a22 = ey.y; + float 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 +{ + float a = ex.x, b = ey.x, c = ex.y, d = ey.y; + float 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 +{ + float det = b2Dot(ex, b2Cross(ey, ez)); + if (det != 0.0f) + { + det = 1.0f / det; + } + + float a11 = ex.x, a12 = ey.x, a13 = ez.x; + float a22 = ey.y, a23 = ez.y; + float 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/libraries/Box2D/Common/b2_settings.cpp b/src/libraries/Box2D/Common/b2_settings.cpp new file mode 100644 index 000000000..11436f7de --- /dev/null +++ b/src/libraries/Box2D/Common/b2_settings.cpp @@ -0,0 +1,77 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#define _CRT_SECURE_NO_WARNINGS + +#include "box2d/b2_settings.h" +#include +#include +#include + +b2Version b2_version = {2, 4, 0}; + +// 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); +} + +FILE* b2_dumpFile = nullptr; + +void b2OpenDump(const char* fileName) +{ + b2Assert(b2_dumpFile == nullptr); + b2_dumpFile = fopen(fileName, "w"); +} + +void b2Dump(const char* string, ...) +{ + if (b2_dumpFile == nullptr) + { + return; + } + + va_list args; + va_start(args, string); + vfprintf(b2_dumpFile, string, args); + va_end(args); +} + +void b2CloseDump() +{ + fclose(b2_dumpFile); + b2_dumpFile = nullptr; +} diff --git a/src/libraries/Box2D/Common/b2_stack_allocator.cpp b/src/libraries/Box2D/Common/b2_stack_allocator.cpp new file mode 100644 index 000000000..602db1a00 --- /dev/null +++ b/src/libraries/Box2D/Common/b2_stack_allocator.cpp @@ -0,0 +1,87 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_stack_allocator.h" +#include "box2d/b2_math.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/libraries/Box2D/Common/b2_timer.cpp b/src/libraries/Box2D/Common/b2_timer.cpp new file mode 100644 index 000000000..dd7cde7f4 --- /dev/null +++ b/src/libraries/Box2D/Common/b2_timer.cpp @@ -0,0 +1,125 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_timer.h" + +#if defined(_WIN32) + +double b2Timer::s_invFrequency = 0.0; + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + +#include + +b2Timer::b2Timer() +{ + LARGE_INTEGER largeInteger; + + if (s_invFrequency == 0.0) + { + QueryPerformanceFrequency(&largeInteger); + s_invFrequency = double(largeInteger.QuadPart); + if (s_invFrequency > 0.0) + { + s_invFrequency = 1000.0 / s_invFrequency; + } + } + + QueryPerformanceCounter(&largeInteger); + m_start = double(largeInteger.QuadPart); +} + +void b2Timer::Reset() +{ + LARGE_INTEGER largeInteger; + QueryPerformanceCounter(&largeInteger); + m_start = double(largeInteger.QuadPart); +} + +float b2Timer::GetMilliseconds() const +{ + LARGE_INTEGER largeInteger; + QueryPerformanceCounter(&largeInteger); + double count = double(largeInteger.QuadPart); + float ms = float(s_invFrequency * (count - m_start)); + return ms; +} + +#elif defined(__linux__) || defined (__APPLE__) + +#include + +b2Timer::b2Timer() +{ + Reset(); +} + +void b2Timer::Reset() +{ + timeval t; + gettimeofday(&t, 0); + m_start_sec = t.tv_sec; + m_start_usec = t.tv_usec; +} + +float 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() +{ +} + +float b2Timer::GetMilliseconds() const +{ + return 0.0f; +} + +#endif diff --git a/src/libraries/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp b/src/libraries/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp deleted file mode 100644 index 01c921f3d..000000000 --- a/src/libraries/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 -#include -#include -#include -#include - -#include - -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/libraries/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.h b/src/libraries/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.h deleted file mode 100644 index b93c30edc..000000000 --- a/src/libraries/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 - -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); -}; - -#endif diff --git a/src/libraries/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp b/src/libraries/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp deleted file mode 100644 index 4642fa46a..000000000 --- a/src/libraries/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 -#include -#include -#include -#include - -#include - -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/libraries/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.h b/src/libraries/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.h deleted file mode 100644 index 0c09af68a..000000000 --- a/src/libraries/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 - -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); -}; - -#endif diff --git a/src/libraries/Box2D/Dynamics/Contacts/b2CircleContact.cpp b/src/libraries/Box2D/Dynamics/Contacts/b2CircleContact.cpp deleted file mode 100644 index b47f35aed..000000000 --- a/src/libraries/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 -#include -#include -#include -#include -#include - -#include - -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/libraries/Box2D/Dynamics/Contacts/b2CircleContact.h b/src/libraries/Box2D/Dynamics/Contacts/b2CircleContact.h deleted file mode 100644 index 079d3abcd..000000000 --- a/src/libraries/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 - -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); -}; - -#endif diff --git a/src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.h b/src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.h deleted file mode 100644 index a622e30d8..000000000 --- a/src/libraries/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 -#include -#include - -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/libraries/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.cpp b/src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.cpp deleted file mode 100644 index d1fd3295c..000000000 --- a/src/libraries/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 -#include -#include - -#include - -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/libraries/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.h b/src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.h deleted file mode 100644 index e7a34553c..000000000 --- a/src/libraries/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 - -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); -}; - -#endif diff --git a/src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp b/src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp deleted file mode 100644 index ba536bc39..000000000 --- a/src/libraries/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 -#include -#include - -#include - -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/libraries/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.h b/src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.h deleted file mode 100644 index 3b40f1216..000000000 --- a/src/libraries/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 - -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); -}; - -#endif diff --git a/src/libraries/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp b/src/libraries/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp deleted file mode 100644 index 7c9cbcc92..000000000 --- a/src/libraries/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 -#include -#include - -#include - -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/libraries/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h b/src/libraries/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h deleted file mode 100644 index fe0645e08..000000000 --- a/src/libraries/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 - -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); -}; - -#endif diff --git a/src/libraries/Box2D/Dynamics/Contacts/b2PolygonContact.cpp b/src/libraries/Box2D/Dynamics/Contacts/b2PolygonContact.cpp deleted file mode 100644 index b5706ca10..000000000 --- a/src/libraries/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 -#include -#include -#include -#include -#include - -#include - -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/libraries/Box2D/Dynamics/Contacts/b2PolygonContact.h b/src/libraries/Box2D/Dynamics/Contacts/b2PolygonContact.h deleted file mode 100644 index 434e6c926..000000000 --- a/src/libraries/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 - -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); -}; - -#endif diff --git a/src/libraries/Box2D/Dynamics/Joints/b2DistanceJoint.h b/src/libraries/Box2D/Dynamics/Joints/b2DistanceJoint.h deleted file mode 100644 index 2faba9d47..000000000 --- a/src/libraries/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 - -/// 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; - b2Vec2 GetAnchorB() const; - - /// Get the reaction force given the inverse time step. - /// Unit is N. - b2Vec2 GetReactionForce(float32 inv_dt) const; - - /// 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; - - /// 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(); - -protected: - - friend class b2Joint; - b2DistanceJoint(const b2DistanceJointDef* data); - - void InitVelocityConstraints(const b2SolverData& data); - void SolveVelocityConstraints(const b2SolverData& data); - bool SolvePositionConstraints(const b2SolverData& data); - - 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/libraries/Box2D/Dynamics/Joints/b2FrictionJoint.h b/src/libraries/Box2D/Dynamics/Joints/b2FrictionJoint.h deleted file mode 100644 index d57abe80d..000000000 --- a/src/libraries/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 - -/// 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; - b2Vec2 GetAnchorB() const; - - b2Vec2 GetReactionForce(float32 inv_dt) const; - float32 GetReactionTorque(float32 inv_dt) const; - - /// 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(); - -protected: - - friend class b2Joint; - - b2FrictionJoint(const b2FrictionJointDef* def); - - void InitVelocityConstraints(const b2SolverData& data); - void SolveVelocityConstraints(const b2SolverData& data); - bool SolvePositionConstraints(const b2SolverData& data); - - 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/libraries/Box2D/Dynamics/Joints/b2GearJoint.h b/src/libraries/Box2D/Dynamics/Joints/b2GearJoint.h deleted file mode 100644 index fd3d7b2fa..000000000 --- a/src/libraries/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 - -/// 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 = NULL; - joint2 = NULL; - 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; - b2Vec2 GetAnchorB() const; - - b2Vec2 GetReactionForce(float32 inv_dt) const; - float32 GetReactionTorque(float32 inv_dt) const; - - /// 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(); - -protected: - - friend class b2Joint; - b2GearJoint(const b2GearJointDef* data); - - void InitVelocityConstraints(const b2SolverData& data); - void SolveVelocityConstraints(const b2SolverData& data); - bool SolvePositionConstraints(const b2SolverData& data); - - 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/libraries/Box2D/Dynamics/Joints/b2Joint.cpp b/src/libraries/Box2D/Dynamics/Joints/b2Joint.cpp deleted file mode 100644 index dd55be94f..000000000 --- a/src/libraries/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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -b2Joint* b2Joint::Create(const b2JointDef* def, b2BlockAllocator* allocator) -{ - b2Joint* joint = NULL; - - switch (def->type) - { - case e_distanceJoint: - { - void* mem = allocator->Allocate(sizeof(b2DistanceJoint)); - joint = new (mem) b2DistanceJoint(static_cast(def)); - } - break; - - case e_mouseJoint: - { - void* mem = allocator->Allocate(sizeof(b2MouseJoint)); - joint = new (mem) b2MouseJoint(static_cast(def)); - } - break; - - case e_prismaticJoint: - { - void* mem = allocator->Allocate(sizeof(b2PrismaticJoint)); - joint = new (mem) b2PrismaticJoint(static_cast(def)); - } - break; - - case e_revoluteJoint: - { - void* mem = allocator->Allocate(sizeof(b2RevoluteJoint)); - joint = new (mem) b2RevoluteJoint(static_cast(def)); - } - break; - - case e_pulleyJoint: - { - void* mem = allocator->Allocate(sizeof(b2PulleyJoint)); - joint = new (mem) b2PulleyJoint(static_cast(def)); - } - break; - - case e_gearJoint: - { - void* mem = allocator->Allocate(sizeof(b2GearJoint)); - joint = new (mem) b2GearJoint(static_cast(def)); - } - break; - - case e_wheelJoint: - { - void* mem = allocator->Allocate(sizeof(b2WheelJoint)); - joint = new (mem) b2WheelJoint(static_cast(def)); - } - break; - - case e_weldJoint: - { - void* mem = allocator->Allocate(sizeof(b2WeldJoint)); - joint = new (mem) b2WeldJoint(static_cast(def)); - } - break; - - case e_frictionJoint: - { - void* mem = allocator->Allocate(sizeof(b2FrictionJoint)); - joint = new (mem) b2FrictionJoint(static_cast(def)); - } - break; - - case e_ropeJoint: - { - void* mem = allocator->Allocate(sizeof(b2RopeJoint)); - joint = new (mem) b2RopeJoint(static_cast(def)); - } - break; - - case e_motorJoint: - { - void* mem = allocator->Allocate(sizeof(b2MotorJoint)); - joint = new (mem) b2MotorJoint(static_cast(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 = NULL; - m_next = NULL; - 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 = NULL; - m_edgeA.other = NULL; - m_edgeA.prev = NULL; - m_edgeA.next = NULL; - - m_edgeB.joint = NULL; - m_edgeB.other = NULL; - m_edgeB.prev = NULL; - m_edgeB.next = NULL; -} - -bool b2Joint::IsActive() const -{ - return m_bodyA->IsActive() && m_bodyB->IsActive(); -} diff --git a/src/libraries/Box2D/Dynamics/Joints/b2MotorJoint.h b/src/libraries/Box2D/Dynamics/Joints/b2MotorJoint.h deleted file mode 100644 index 0b76d6fe7..000000000 --- a/src/libraries/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 - -/// 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; - b2Vec2 GetAnchorB() const; - - b2Vec2 GetReactionForce(float32 inv_dt) const; - float32 GetReactionTorque(float32 inv_dt) const; - - /// 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(); - -protected: - - friend class b2Joint; - - b2MotorJoint(const b2MotorJointDef* def); - - void InitVelocityConstraints(const b2SolverData& data); - void SolveVelocityConstraints(const b2SolverData& data); - bool SolvePositionConstraints(const b2SolverData& data); - - // 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/libraries/Box2D/Dynamics/Joints/b2MouseJoint.h b/src/libraries/Box2D/Dynamics/Joints/b2MouseJoint.h deleted file mode 100644 index 8b50a0e14..000000000 --- a/src/libraries/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 - -/// 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; - - /// Implements b2Joint. - b2Vec2 GetAnchorB() const; - - /// Implements b2Joint. - b2Vec2 GetReactionForce(float32 inv_dt) const; - - /// Implements b2Joint. - float32 GetReactionTorque(float32 inv_dt) const; - - /// 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() { b2Log("Mouse joint dumping is not supported.\n"); } - - /// Implement b2Joint::ShiftOrigin - void ShiftOrigin(const b2Vec2& newOrigin); - -protected: - friend class b2Joint; - - b2MouseJoint(const b2MouseJointDef* def); - - void InitVelocityConstraints(const b2SolverData& data); - void SolveVelocityConstraints(const b2SolverData& data); - bool SolvePositionConstraints(const b2SolverData& data); - - 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/libraries/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp b/src/libraries/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp deleted file mode 100644 index 217e14502..000000000 --- a/src/libraries/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp +++ /dev/null @@ -1,629 +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 -#include -#include - -// 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 s1test; - s1test = b2Cross(rA, 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; -} - -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) -{ - m_bodyA->SetAwake(true); - m_bodyB->SetAwake(true); - m_enableMotor = flag; -} - -void b2PrismaticJoint::SetMotorSpeed(float32 speed) -{ - m_bodyA->SetAwake(true); - m_bodyB->SetAwake(true); - m_motorSpeed = speed; -} - -void b2PrismaticJoint::SetMaxMotorForce(float32 force) -{ - 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/libraries/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp b/src/libraries/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp deleted file mode 100644 index 64bd19070..000000000 --- a/src/libraries/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp +++ /dev/null @@ -1,502 +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 -#include -#include - -// 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) -{ - 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) -{ - m_bodyA->SetAwake(true); - m_bodyB->SetAwake(true); - m_motorSpeed = speed; -} - -void b2RevoluteJoint::SetMaxMotorTorque(float32 torque) -{ - 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/libraries/Box2D/Dynamics/Joints/b2RopeJoint.h b/src/libraries/Box2D/Dynamics/Joints/b2RopeJoint.h deleted file mode 100644 index eaca575d0..000000000 --- a/src/libraries/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 - -/// 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; - b2Vec2 GetAnchorB() const; - - b2Vec2 GetReactionForce(float32 inv_dt) const; - float32 GetReactionTorque(float32 inv_dt) const; - - /// 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(); - -protected: - - friend class b2Joint; - b2RopeJoint(const b2RopeJointDef* data); - - void InitVelocityConstraints(const b2SolverData& data); - void SolveVelocityConstraints(const b2SolverData& data); - bool SolvePositionConstraints(const b2SolverData& data); - - // 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/libraries/Box2D/Dynamics/Joints/b2WeldJoint.h b/src/libraries/Box2D/Dynamics/Joints/b2WeldJoint.h deleted file mode 100644 index eed9bc103..000000000 --- a/src/libraries/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 - -/// 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; - b2Vec2 GetAnchorB() const; - - b2Vec2 GetReactionForce(float32 inv_dt) const; - float32 GetReactionTorque(float32 inv_dt) const; - - /// 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(); - -protected: - - friend class b2Joint; - - b2WeldJoint(const b2WeldJointDef* def); - - void InitVelocityConstraints(const b2SolverData& data); - void SolveVelocityConstraints(const b2SolverData& data); - bool SolvePositionConstraints(const b2SolverData& data); - - 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/libraries/Box2D/Dynamics/Joints/b2WheelJoint.cpp b/src/libraries/Box2D/Dynamics/Joints/b2WheelJoint.cpp deleted file mode 100644 index c9f6de600..000000000 --- a/src/libraries/Box2D/Dynamics/Joints/b2WheelJoint.cpp +++ /dev/null @@ -1,419 +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 -#include -#include - -// 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 d = 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 * (d + 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::GetJointSpeed() 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) -{ - m_bodyA->SetAwake(true); - m_bodyB->SetAwake(true); - m_enableMotor = flag; -} - -void b2WheelJoint::SetMotorSpeed(float32 speed) -{ - m_bodyA->SetAwake(true); - m_bodyB->SetAwake(true); - m_motorSpeed = speed; -} - -void b2WheelJoint::SetMaxMotorTorque(float32 torque) -{ - 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/libraries/Box2D/Dynamics/Joints/b2WheelJoint.h b/src/libraries/Box2D/Dynamics/Joints/b2WheelJoint.h deleted file mode 100644 index a33c77f4b..000000000 --- a/src/libraries/Box2D/Dynamics/Joints/b2WheelJoint.h +++ /dev/null @@ -1,210 +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 - -/// 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; - b2Vec2 GetAnchorB() const; - - b2Vec2 GetReactionForce(float32 inv_dt) const; - float32 GetReactionTorque(float32 inv_dt) const; - - /// 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 translation speed, usually in meters per second. - float32 GetJointSpeed() 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(); - -protected: - - friend class b2Joint; - b2WheelJoint(const b2WheelJointDef* def); - - void InitVelocityConstraints(const b2SolverData& data); - void SolveVelocityConstraints(const b2SolverData& data); - bool SolvePositionConstraints(const b2SolverData& data); - - 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/libraries/Box2D/Dynamics/b2ContactManager.h b/src/libraries/Box2D/Dynamics/b2ContactManager.h deleted file mode 100644 index 6a1d072af..000000000 --- a/src/libraries/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 - -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/libraries/Box2D/Dynamics/b2TimeStep.h b/src/libraries/Box2D/Dynamics/b2TimeStep.h deleted file mode 100644 index a3727624c..000000000 --- a/src/libraries/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 - -/// 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/libraries/Box2D/Dynamics/b2WorldCallbacks.cpp b/src/libraries/Box2D/Dynamics/b2WorldCallbacks.cpp deleted file mode 100644 index 0f4b9c53c..000000000 --- a/src/libraries/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 -#include - -// 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/libraries/Box2D/Dynamics/b2Body.cpp b/src/libraries/Box2D/Dynamics/b2_body.cpp similarity index 70% rename from src/libraries/Box2D/Dynamics/b2Body.cpp rename to src/libraries/Box2D/Dynamics/b2_body.cpp index b6550531f..39851c4cb 100644 --- a/src/libraries/Box2D/Dynamics/b2Body.cpp +++ b/src/libraries/Box2D/Dynamics/b2_body.cpp @@ -1,26 +1,32 @@ -/* -* 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. -*/ +// MIT License -#include -#include -#include -#include -#include +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_body.h" +#include "box2d/b2_contact.h" +#include "box2d/b2_fixture.h" +#include "box2d/b2_joint.h" +#include "box2d/b2_world.h" + +#include b2Body::b2Body(const b2BodyDef* bd, b2World* world) { @@ -45,13 +51,13 @@ b2Body::b2Body(const b2BodyDef* bd, b2World* world) { m_flags |= e_autoSleepFlag; } - if (bd->awake) + if (bd->awake && bd->type != b2_staticBody) { m_flags |= e_awakeFlag; } - if (bd->active) + if (bd->enabled) { - m_flags |= e_activeFlag; + m_flags |= e_enabledFlag; } m_world = world; @@ -66,10 +72,10 @@ b2Body::b2Body(const b2BodyDef* bd, b2World* world) m_sweep.a = bd->angle; m_sweep.alpha0 = 0.0f; - m_jointList = NULL; - m_contactList = NULL; - m_prev = NULL; - m_next = NULL; + m_jointList = nullptr; + m_contactList = nullptr; + m_prev = nullptr; + m_next = nullptr; m_linearVelocity = bd->linearVelocity; m_angularVelocity = bd->angularVelocity; @@ -85,23 +91,15 @@ b2Body::b2Body(const b2BodyDef* bd, b2World* world) 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_mass = 0.0f; + m_invMass = 0.0f; m_I = 0.0f; m_invI = 0.0f; m_userData = bd->userData; - m_fixtureList = NULL; + m_fixtureList = nullptr; m_fixtureCount = 0; } @@ -133,6 +131,7 @@ void b2Body::SetType(b2BodyType type) m_angularVelocity = 0.0f; m_sweep.a0 = m_sweep.a; m_sweep.c0 = m_sweep.c; + m_flags &= ~e_awakeFlag; SynchronizeFixtures(); } @@ -149,7 +148,7 @@ void b2Body::SetType(b2BodyType type) ce = ce->next; m_world->m_contactManager.Destroy(ce0->contact); } - m_contactList = NULL; + m_contactList = nullptr; // Touch the proxies so that new contacts will be created (when appropriate) b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase; @@ -168,7 +167,7 @@ b2Fixture* b2Body::CreateFixture(const b2FixtureDef* def) b2Assert(m_world->IsLocked() == false); if (m_world->IsLocked() == true) { - return NULL; + return nullptr; } b2BlockAllocator* allocator = &m_world->m_blockAllocator; @@ -177,7 +176,7 @@ b2Fixture* b2Body::CreateFixture(const b2FixtureDef* def) b2Fixture* fixture = new (memory) b2Fixture; fixture->Create(allocator, this, def); - if (m_flags & e_activeFlag) + if (m_flags & e_enabledFlag) { b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase; fixture->CreateProxies(broadPhase, m_xf); @@ -197,12 +196,12 @@ b2Fixture* b2Body::CreateFixture(const b2FixtureDef* def) // 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; + m_world->m_newContacts = true; return fixture; } -b2Fixture* b2Body::CreateFixture(const b2Shape* shape, float32 density) +b2Fixture* b2Body::CreateFixture(const b2Shape* shape, float density) { b2FixtureDef def; def.shape = shape; @@ -213,6 +212,11 @@ b2Fixture* b2Body::CreateFixture(const b2Shape* shape, float32 density) void b2Body::DestroyFixture(b2Fixture* fixture) { + if (fixture == NULL) + { + return; + } + b2Assert(m_world->IsLocked() == false); if (m_world->IsLocked() == true) { @@ -225,7 +229,7 @@ void b2Body::DestroyFixture(b2Fixture* fixture) b2Assert(m_fixtureCount > 0); b2Fixture** node = &m_fixtureList; bool found = false; - while (*node != NULL) + while (*node != nullptr) { if (*node == fixture) { @@ -260,15 +264,15 @@ void b2Body::DestroyFixture(b2Fixture* fixture) b2BlockAllocator* allocator = &m_world->m_blockAllocator; - if (m_flags & e_activeFlag) + if (m_flags & e_enabledFlag) { b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase; fixture->DestroyProxies(broadPhase); } + fixture->m_body = nullptr; + fixture->m_next = nullptr; fixture->Destroy(allocator); - fixture->m_body = NULL; - fixture->m_next = NULL; fixture->~b2Fixture(); allocator->Free(fixture, sizeof(b2Fixture)); @@ -320,12 +324,6 @@ void b2Body::ResetMassData() 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) { @@ -414,7 +412,7 @@ bool b2Body::ShouldCollide(const b2Body* other) const return true; } -void b2Body::SetTransform(const b2Vec2& position, float32 angle) +void b2Body::SetTransform(const b2Vec2& position, float angle) { b2Assert(m_world->IsLocked() == false); if (m_world->IsLocked() == true) @@ -440,29 +438,40 @@ void b2Body::SetTransform(const b2Vec2& position, float32 angle) 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) + + if (m_flags & b2Body::e_awakeFlag) { - f->Synchronize(broadPhase, xf1, m_xf); + b2Transform xf1; + xf1.q.Set(m_sweep.a0); + xf1.p = m_sweep.c0 - b2Mul(xf1.q, m_sweep.localCenter); + + for (b2Fixture* f = m_fixtureList; f; f = f->m_next) + { + f->Synchronize(broadPhase, xf1, m_xf); + } + } + else + { + for (b2Fixture* f = m_fixtureList; f; f = f->m_next) + { + f->Synchronize(broadPhase, m_xf, m_xf); + } } } -void b2Body::SetActive(bool flag) +void b2Body::SetEnabled(bool flag) { b2Assert(m_world->IsLocked() == false); - if (flag == IsActive()) + if (flag == IsEnabled()) { return; } if (flag) { - m_flags |= e_activeFlag; + m_flags |= e_enabledFlag; // Create all proxies. b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase; @@ -471,11 +480,12 @@ void b2Body::SetActive(bool flag) f->CreateProxies(broadPhase, m_xf); } - // Contacts are created the next time step. + // Contacts are created at the beginning of the next + m_world->m_newContacts = true; } else { - m_flags &= ~e_activeFlag; + m_flags &= ~e_enabledFlag; // Destroy all proxies. b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase; @@ -492,7 +502,7 @@ void b2Body::SetActive(bool flag) ce = ce->next; m_world->m_contactManager.Destroy(ce0->contact); } - m_contactList = NULL; + m_contactList = nullptr; } } @@ -522,28 +532,31 @@ 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"); + // %.9g is sufficient to save and load the same value using text + // FLT_DECIMAL_DIG == 9 + + b2Dump("{\n"); + b2Dump(" b2BodyDef bd;\n"); + b2Dump(" bd.type = b2BodyType(%d);\n", m_type); + b2Dump(" bd.position.Set(%.9g, %.9g);\n", m_xf.p.x, m_xf.p.y); + b2Dump(" bd.angle = %.9g;\n", m_sweep.a); + b2Dump(" bd.linearVelocity.Set(%.9g, %.9g);\n", m_linearVelocity.x, m_linearVelocity.y); + b2Dump(" bd.angularVelocity = %.9g;\n", m_angularVelocity); + b2Dump(" bd.linearDamping = %.9g;\n", m_linearDamping); + b2Dump(" bd.angularDamping = %.9g;\n", m_angularDamping); + b2Dump(" bd.allowSleep = bool(%d);\n", m_flags & e_autoSleepFlag); + b2Dump(" bd.awake = bool(%d);\n", m_flags & e_awakeFlag); + b2Dump(" bd.fixedRotation = bool(%d);\n", m_flags & e_fixedRotationFlag); + b2Dump(" bd.bullet = bool(%d);\n", m_flags & e_bulletFlag); + b2Dump(" bd.enabled = bool(%d);\n", m_flags & e_enabledFlag); + b2Dump(" bd.gravityScale = %.9g;\n", m_gravityScale); + b2Dump(" bodies[%d] = m_world->CreateBody(&bd);\n", m_islandIndex); + b2Dump("\n"); for (b2Fixture* f = m_fixtureList; f; f = f->m_next) { - b2Log(" {\n"); + b2Dump(" {\n"); f->Dump(bodyIndex); - b2Log(" }\n"); + b2Dump(" }\n"); } - b2Log("}\n"); + b2Dump("}\n"); } diff --git a/src/libraries/Box2D/Dynamics/b2_chain_circle_contact.cpp b/src/libraries/Box2D/Dynamics/b2_chain_circle_contact.cpp new file mode 100644 index 000000000..8464fe836 --- /dev/null +++ b/src/libraries/Box2D/Dynamics/b2_chain_circle_contact.cpp @@ -0,0 +1,57 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "b2_chain_circle_contact.h" +#include "box2d/b2_block_allocator.h" +#include "box2d/b2_fixture.h" +#include "box2d/b2_chain_shape.h" +#include "box2d/b2_edge_shape.h" + +#include + +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/libraries/Box2D/Dynamics/b2_chain_circle_contact.h b/src/libraries/Box2D/Dynamics/b2_chain_circle_contact.h new file mode 100644 index 000000000..33ced64d8 --- /dev/null +++ b/src/libraries/Box2D/Dynamics/b2_chain_circle_contact.h @@ -0,0 +1,43 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_CHAIN_AND_CIRCLE_CONTACT_H +#define B2_CHAIN_AND_CIRCLE_CONTACT_H + +#include "box2d/b2_contact.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/libraries/Box2D/Dynamics/b2_chain_polygon_contact.cpp b/src/libraries/Box2D/Dynamics/b2_chain_polygon_contact.cpp new file mode 100644 index 000000000..b8257aab9 --- /dev/null +++ b/src/libraries/Box2D/Dynamics/b2_chain_polygon_contact.cpp @@ -0,0 +1,57 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "b2_chain_polygon_contact.h" +#include "box2d/b2_block_allocator.h" +#include "box2d/b2_fixture.h" +#include "box2d/b2_chain_shape.h" +#include "box2d/b2_edge_shape.h" + +#include + +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/libraries/Box2D/Dynamics/b2_chain_polygon_contact.h b/src/libraries/Box2D/Dynamics/b2_chain_polygon_contact.h new file mode 100644 index 000000000..058154fb1 --- /dev/null +++ b/src/libraries/Box2D/Dynamics/b2_chain_polygon_contact.h @@ -0,0 +1,43 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_CHAIN_AND_POLYGON_CONTACT_H +#define B2_CHAIN_AND_POLYGON_CONTACT_H + +#include "box2d/b2_contact.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/libraries/Box2D/Dynamics/b2_circle_contact.cpp b/src/libraries/Box2D/Dynamics/b2_circle_contact.cpp new file mode 100644 index 000000000..738aa84ca --- /dev/null +++ b/src/libraries/Box2D/Dynamics/b2_circle_contact.cpp @@ -0,0 +1,56 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "b2_circle_contact.h" +#include "box2d/b2_block_allocator.h" +#include "box2d/b2_body.h" +#include "box2d/b2_fixture.h" +#include "box2d/b2_time_of_impact.h" +#include "box2d/b2_world_callbacks.h" + +#include + +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/libraries/Box2D/Dynamics/b2_circle_contact.h b/src/libraries/Box2D/Dynamics/b2_circle_contact.h new file mode 100644 index 000000000..98e09ea5b --- /dev/null +++ b/src/libraries/Box2D/Dynamics/b2_circle_contact.h @@ -0,0 +1,43 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_CIRCLE_CONTACT_H +#define B2_CIRCLE_CONTACT_H + +#include "box2d/b2_contact.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/libraries/Box2D/Dynamics/Contacts/b2Contact.cpp b/src/libraries/Box2D/Dynamics/b2_contact.cpp similarity index 72% rename from src/libraries/Box2D/Dynamics/Contacts/b2Contact.cpp rename to src/libraries/Box2D/Dynamics/b2_contact.cpp index d9f1021e4..7c95649d0 100644 --- a/src/libraries/Box2D/Dynamics/Contacts/b2Contact.cpp +++ b/src/libraries/Box2D/Dynamics/b2_contact.cpp @@ -1,38 +1,42 @@ -/* -* 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. -*/ +// MIT License -#include -#include -#include -#include -#include -#include -#include -#include -#include +// Copyright (c) 2019 Erin Catto -#include -#include -#include -#include -#include -#include -#include +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "b2_chain_circle_contact.h" +#include "b2_chain_polygon_contact.h" +#include "b2_circle_contact.h" +#include "b2_contact_solver.h" +#include "b2_edge_circle_contact.h" +#include "b2_edge_polygon_contact.h" +#include "b2_polygon_circle_contact.h" +#include "b2_polygon_contact.h" + +#include "box2d/b2_contact.h" +#include "box2d/b2_block_allocator.h" +#include "box2d/b2_body.h" +#include "box2d/b2_collision.h" +#include "box2d/b2_fixture.h" +#include "box2d/b2_shape.h" +#include "box2d/b2_time_of_impact.h" +#include "box2d/b2_world.h" b2ContactRegister b2Contact::s_registers[b2Shape::e_typeCount][b2Shape::e_typeCount]; bool b2Contact::s_initialized = false; @@ -94,7 +98,7 @@ b2Contact* b2Contact::Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtu } else { - return NULL; + return nullptr; } } @@ -116,8 +120,8 @@ void b2Contact::Destroy(b2Contact* contact, b2BlockAllocator* allocator) b2Shape::Type typeA = fixtureA->GetType(); b2Shape::Type typeB = fixtureB->GetType(); - b2Assert(0 <= typeA && typeB < b2Shape::e_typeCount); - b2Assert(0 <= typeA && typeB < b2Shape::e_typeCount); + b2Assert(0 <= typeA && typeA < b2Shape::e_typeCount); + b2Assert(0 <= typeB && typeB < b2Shape::e_typeCount); b2ContactDestroyFcn* destroyFcn = s_registers[typeA][typeB].destroyFcn; destroyFcn(contact, allocator); @@ -135,18 +139,18 @@ b2Contact::b2Contact(b2Fixture* fA, int32 indexA, b2Fixture* fB, int32 indexB) m_manifold.pointCount = 0; - m_prev = NULL; - m_next = NULL; + m_prev = nullptr; + m_next = nullptr; - m_nodeA.contact = NULL; - m_nodeA.prev = NULL; - m_nodeA.next = NULL; - m_nodeA.other = NULL; + m_nodeA.contact = nullptr; + m_nodeA.prev = nullptr; + m_nodeA.next = nullptr; + m_nodeA.other = nullptr; - m_nodeB.contact = NULL; - m_nodeB.prev = NULL; - m_nodeB.next = NULL; - m_nodeB.other = NULL; + m_nodeB.contact = nullptr; + m_nodeB.prev = nullptr; + m_nodeB.next = nullptr; + m_nodeB.other = nullptr; m_toiCount = 0; diff --git a/src/libraries/Box2D/Dynamics/b2ContactManager.cpp b/src/libraries/Box2D/Dynamics/b2_contact_manager.cpp similarity index 78% rename from src/libraries/Box2D/Dynamics/b2ContactManager.cpp rename to src/libraries/Box2D/Dynamics/b2_contact_manager.cpp index d8a189b74..56666084c 100644 --- a/src/libraries/Box2D/Dynamics/b2ContactManager.cpp +++ b/src/libraries/Box2D/Dynamics/b2_contact_manager.cpp @@ -1,37 +1,41 @@ -/* -* 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. -*/ +// MIT License -#include -#include -#include -#include -#include +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_body.h" +#include "box2d/b2_contact.h" +#include "box2d/b2_contact_manager.h" +#include "box2d/b2_fixture.h" +#include "box2d/b2_world_callbacks.h" b2ContactFilter b2_defaultFilter; b2ContactListener b2_defaultListener; b2ContactManager::b2ContactManager() { - m_contactList = NULL; + m_contactList = nullptr; m_contactCount = 0; m_contactFilter = &b2_defaultFilter; m_contactListener = &b2_defaultListener; - m_allocator = NULL; + m_allocator = nullptr; } void b2ContactManager::Destroy(b2Contact* c) @@ -237,7 +241,7 @@ void b2ContactManager::AddPair(void* proxyUserDataA, void* proxyUserDataB) // Call the factory. b2Contact* c = b2Contact::Create(fixtureA, indexA, fixtureB, indexB, m_allocator); - if (c == NULL) + if (c == nullptr) { return; } @@ -251,9 +255,9 @@ void b2ContactManager::AddPair(void* proxyUserDataA, void* proxyUserDataB) bodyB = fixtureB->GetBody(); // Insert into the world. - c->m_prev = NULL; + c->m_prev = nullptr; c->m_next = m_contactList; - if (m_contactList != NULL) + if (m_contactList != nullptr) { m_contactList->m_prev = c; } @@ -265,9 +269,9 @@ void b2ContactManager::AddPair(void* proxyUserDataA, void* proxyUserDataB) c->m_nodeA.contact = c; c->m_nodeA.other = bodyB; - c->m_nodeA.prev = NULL; + c->m_nodeA.prev = nullptr; c->m_nodeA.next = bodyA->m_contactList; - if (bodyA->m_contactList != NULL) + if (bodyA->m_contactList != nullptr) { bodyA->m_contactList->prev = &c->m_nodeA; } @@ -277,20 +281,13 @@ void b2ContactManager::AddPair(void* proxyUserDataA, void* proxyUserDataB) c->m_nodeB.contact = c; c->m_nodeB.other = bodyA; - c->m_nodeB.prev = NULL; + c->m_nodeB.prev = nullptr; c->m_nodeB.next = bodyB->m_contactList; - if (bodyB->m_contactList != NULL) + 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/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.cpp b/src/libraries/Box2D/Dynamics/b2_contact_solver.cpp similarity index 79% rename from src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.cpp rename to src/libraries/Box2D/Dynamics/b2_contact_solver.cpp index e31b6c236..f60a2086e 100644 --- a/src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.cpp +++ b/src/libraries/Box2D/Dynamics/b2_contact_solver.cpp @@ -1,29 +1,34 @@ -/* -* 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. -*/ +// MIT License -#include +// Copyright (c) 2019 Erin Catto -#include -#include -#include -#include -#include +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "b2_contact_solver.h" + +#include "box2d/b2_body.h" +#include "box2d/b2_contact.h" +#include "box2d/b2_fixture.h" +#include "box2d/b2_stack_allocator.h" +#include "box2d/b2_world.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; @@ -35,11 +40,11 @@ struct b2ContactPositionConstraint b2Vec2 localPoint; int32 indexA; int32 indexB; - float32 invMassA, invMassB; + float invMassA, invMassB; b2Vec2 localCenterA, localCenterB; - float32 invIA, invIB; + float invIA, invIB; b2Manifold::Type type; - float32 radiusA, radiusB; + float radiusA, radiusB; int32 pointCount; }; @@ -63,8 +68,8 @@ b2ContactSolver::b2ContactSolver(b2ContactSolverDef* def) b2Fixture* fixtureB = contact->m_fixtureB; b2Shape* shapeA = fixtureA->GetShape(); b2Shape* shapeB = fixtureB->GetShape(); - float32 radiusA = shapeA->m_radius; - float32 radiusB = shapeB->m_radius; + float radiusA = shapeA->m_radius; + float radiusB = shapeB->m_radius; b2Body* bodyA = fixtureA->GetBody(); b2Body* bodyB = fixtureB->GetBody(); b2Manifold* manifold = contact->GetManifold(); @@ -144,29 +149,29 @@ void b2ContactSolver::InitializeVelocityConstraints() b2ContactVelocityConstraint* vc = m_velocityConstraints + i; b2ContactPositionConstraint* pc = m_positionConstraints + i; - float32 radiusA = pc->radiusA; - float32 radiusB = pc->radiusB; + float radiusA = pc->radiusA; + float 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; + float mA = vc->invMassA; + float mB = vc->invMassB; + float iA = vc->invIA; + float iB = vc->invIB; b2Vec2 localCenterA = pc->localCenterA; b2Vec2 localCenterB = pc->localCenterB; b2Vec2 cA = m_positions[indexA].c; - float32 aA = m_positions[indexA].a; + float aA = m_positions[indexA].a; b2Vec2 vA = m_velocities[indexA].v; - float32 wA = m_velocities[indexA].w; + float wA = m_velocities[indexA].w; b2Vec2 cB = m_positions[indexB].c; - float32 aB = m_positions[indexB].a; + float aB = m_positions[indexB].a; b2Vec2 vB = m_velocities[indexB].v; - float32 wB = m_velocities[indexB].w; + float wB = m_velocities[indexB].w; b2Assert(manifold->pointCount > 0); @@ -189,25 +194,25 @@ void b2ContactSolver::InitializeVelocityConstraints() 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); + float rnA = b2Cross(vcp->rA, vc->normal); + float rnB = b2Cross(vcp->rB, vc->normal); - float32 kNormal = mA + mB + iA * rnA * rnA + iB * rnB * rnB; + float 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); + float rtA = b2Cross(vcp->rA, tangent); + float rtB = b2Cross(vcp->rB, tangent); - float32 kTangent = mA + mB + iA * rtA * rtA + iB * rtB * rtB; + float 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)); + float vRel = b2Dot(vc->normal, vB + b2Cross(wB, vcp->rB) - vA - b2Cross(wA, vcp->rA)); if (vRel < -b2_velocityThreshold) { vcp->velocityBias = -vc->restitution * vRel; @@ -220,17 +225,17 @@ void b2ContactSolver::InitializeVelocityConstraints() 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); + float rn1A = b2Cross(vcp1->rA, vc->normal); + float rn1B = b2Cross(vcp1->rB, vc->normal); + float rn2A = b2Cross(vcp2->rA, vc->normal); + float 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; + float k11 = mA + mB + iA * rn1A * rn1A + iB * rn1B * rn1B; + float k22 = mA + mB + iA * rn2A * rn2A + iB * rn2B * rn2B; + float k12 = mA + mB + iA * rn1A * rn2A + iB * rn1B * rn2B; // Ensure a reasonable condition number. - const float32 k_maxConditionNumber = 1000.0f; + const float k_maxConditionNumber = 1000.0f; if (k11 * k11 < k_maxConditionNumber * (k11 * k22 - k12 * k12)) { // K is safe to invert. @@ -257,16 +262,16 @@ void b2ContactSolver::WarmStart() int32 indexA = vc->indexA; int32 indexB = vc->indexB; - float32 mA = vc->invMassA; - float32 iA = vc->invIA; - float32 mB = vc->invMassB; - float32 iB = vc->invIB; + float mA = vc->invMassA; + float iA = vc->invIA; + float mB = vc->invMassB; + float iB = vc->invIB; int32 pointCount = vc->pointCount; b2Vec2 vA = m_velocities[indexA].v; - float32 wA = m_velocities[indexA].w; + float wA = m_velocities[indexA].w; b2Vec2 vB = m_velocities[indexB].v; - float32 wB = m_velocities[indexB].w; + float wB = m_velocities[indexB].w; b2Vec2 normal = vc->normal; b2Vec2 tangent = b2Cross(normal, 1.0f); @@ -296,20 +301,20 @@ void b2ContactSolver::SolveVelocityConstraints() int32 indexA = vc->indexA; int32 indexB = vc->indexB; - float32 mA = vc->invMassA; - float32 iA = vc->invIA; - float32 mB = vc->invMassB; - float32 iB = vc->invIB; + float mA = vc->invMassA; + float iA = vc->invIA; + float mB = vc->invMassB; + float iB = vc->invIB; int32 pointCount = vc->pointCount; b2Vec2 vA = m_velocities[indexA].v; - float32 wA = m_velocities[indexA].w; + float wA = m_velocities[indexA].w; b2Vec2 vB = m_velocities[indexB].v; - float32 wB = m_velocities[indexB].w; + float wB = m_velocities[indexB].w; b2Vec2 normal = vc->normal; b2Vec2 tangent = b2Cross(normal, 1.0f); - float32 friction = vc->friction; + float friction = vc->friction; b2Assert(pointCount == 1 || pointCount == 2); @@ -323,12 +328,12 @@ void b2ContactSolver::SolveVelocityConstraints() 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); + float vt = b2Dot(dv, tangent) - vc->tangentSpeed; + float lambda = vcp->tangentMass * (-vt); // b2Clamp the accumulated force - float32 maxFriction = friction * vcp->normalImpulse; - float32 newImpulse = b2Clamp(vcp->tangentImpulse + lambda, -maxFriction, maxFriction); + float maxFriction = friction * vcp->normalImpulse; + float newImpulse = b2Clamp(vcp->tangentImpulse + lambda, -maxFriction, maxFriction); lambda = newImpulse - vcp->tangentImpulse; vcp->tangentImpulse = newImpulse; @@ -345,19 +350,19 @@ void b2ContactSolver::SolveVelocityConstraints() // Solve normal constraints if (pointCount == 1 || g_blockSolve == false) { - for (int32 i = 0; i < pointCount; ++i) + for (int32 j = 0; j < pointCount; ++j) { - b2VelocityConstraintPoint* vcp = vc->points + i; + 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); + float vn = b2Dot(dv, normal); + float lambda = -vcp->normalMass * (vn - vcp->velocityBias); // b2Clamp the accumulated impulse - float32 newImpulse = b2Max(vcp->normalImpulse + lambda, 0.0f); + float newImpulse = b2Max(vcp->normalImpulse + lambda, 0.0f); lambda = newImpulse - vcp->normalImpulse; vcp->normalImpulse = newImpulse; @@ -375,7 +380,7 @@ void b2ContactSolver::SolveVelocityConstraints() // 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, , vn >= 0, x >= 0 and vn_i * x_i = 0 with i = 1..2 + // 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 @@ -416,8 +421,8 @@ void b2ContactSolver::SolveVelocityConstraints() 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); + float vn1 = b2Dot(dv1, normal); + float vn2 = b2Dot(dv2, normal); b2Vec2 b; b.x = vn1 - cp1->velocityBias; @@ -426,7 +431,7 @@ void b2ContactSolver::SolveVelocityConstraints() // Compute b' b -= b2Mul(vc->K, a); - const float32 k_errorTol = 1e-3f; + const float k_errorTol = 1e-3f; B2_NOT_USED(k_errorTol); for (;;) @@ -485,7 +490,6 @@ void b2ContactSolver::SolveVelocityConstraints() 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 @@ -664,13 +668,13 @@ struct b2PositionSolverManifold b2Vec2 normal; b2Vec2 point; - float32 separation; + float separation; }; // Sequential solver. bool b2ContactSolver::SolvePositionConstraints() { - float32 minSeparation = 0.0f; + float minSeparation = 0.0f; for (int32 i = 0; i < m_count; ++i) { @@ -679,18 +683,18 @@ bool b2ContactSolver::SolvePositionConstraints() int32 indexA = pc->indexA; int32 indexB = pc->indexB; b2Vec2 localCenterA = pc->localCenterA; - float32 mA = pc->invMassA; - float32 iA = pc->invIA; + float mA = pc->invMassA; + float iA = pc->invIA; b2Vec2 localCenterB = pc->localCenterB; - float32 mB = pc->invMassB; - float32 iB = pc->invIB; + float mB = pc->invMassB; + float iB = pc->invIB; int32 pointCount = pc->pointCount; b2Vec2 cA = m_positions[indexA].c; - float32 aA = m_positions[indexA].a; + float aA = m_positions[indexA].a; b2Vec2 cB = m_positions[indexB].c; - float32 aB = m_positions[indexB].a; + float aB = m_positions[indexB].a; // Solve normal constraints for (int32 j = 0; j < pointCount; ++j) @@ -706,7 +710,7 @@ bool b2ContactSolver::SolvePositionConstraints() b2Vec2 normal = psm.normal; b2Vec2 point = psm.point; - float32 separation = psm.separation; + float separation = psm.separation; b2Vec2 rA = point - cA; b2Vec2 rB = point - cB; @@ -715,15 +719,15 @@ bool b2ContactSolver::SolvePositionConstraints() minSeparation = b2Min(minSeparation, separation); // Prevent large corrections and allow slop. - float32 C = b2Clamp(b2_baumgarte * (separation + b2_linearSlop), -b2_maxLinearCorrection, 0.0f); + float 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; + float rnA = b2Cross(rA, normal); + float rnB = b2Cross(rB, normal); + float K = mA + mB + iA * rnA * rnA + iB * rnB * rnB; // Compute normal impulse - float32 impulse = K > 0.0f ? - C / K : 0.0f; + float impulse = K > 0.0f ? - C / K : 0.0f; b2Vec2 P = impulse * normal; @@ -749,7 +753,7 @@ bool b2ContactSolver::SolvePositionConstraints() // Sequential position solver for position constraints. bool b2ContactSolver::SolveTOIPositionConstraints(int32 toiIndexA, int32 toiIndexB) { - float32 minSeparation = 0.0f; + float minSeparation = 0.0f; for (int32 i = 0; i < m_count; ++i) { @@ -761,16 +765,16 @@ bool b2ContactSolver::SolveTOIPositionConstraints(int32 toiIndexA, int32 toiInde b2Vec2 localCenterB = pc->localCenterB; int32 pointCount = pc->pointCount; - float32 mA = 0.0f; - float32 iA = 0.0f; + float mA = 0.0f; + float iA = 0.0f; if (indexA == toiIndexA || indexA == toiIndexB) { mA = pc->invMassA; iA = pc->invIA; } - float32 mB = 0.0f; - float32 iB = 0.; + float mB = 0.0f; + float iB = 0.; if (indexB == toiIndexA || indexB == toiIndexB) { mB = pc->invMassB; @@ -778,10 +782,10 @@ bool b2ContactSolver::SolveTOIPositionConstraints(int32 toiIndexA, int32 toiInde } b2Vec2 cA = m_positions[indexA].c; - float32 aA = m_positions[indexA].a; + float aA = m_positions[indexA].a; b2Vec2 cB = m_positions[indexB].c; - float32 aB = m_positions[indexB].a; + float aB = m_positions[indexB].a; // Solve normal constraints for (int32 j = 0; j < pointCount; ++j) @@ -797,7 +801,7 @@ bool b2ContactSolver::SolveTOIPositionConstraints(int32 toiIndexA, int32 toiInde b2Vec2 normal = psm.normal; b2Vec2 point = psm.point; - float32 separation = psm.separation; + float separation = psm.separation; b2Vec2 rA = point - cA; b2Vec2 rB = point - cB; @@ -806,15 +810,15 @@ bool b2ContactSolver::SolveTOIPositionConstraints(int32 toiIndexA, int32 toiInde minSeparation = b2Min(minSeparation, separation); // Prevent large corrections and allow slop. - float32 C = b2Clamp(b2_toiBaugarte * (separation + b2_linearSlop), -b2_maxLinearCorrection, 0.0f); + float C = b2Clamp(b2_toiBaumgarte * (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; + float rnA = b2Cross(rA, normal); + float rnB = b2Cross(rB, normal); + float K = mA + mB + iA * rnA * rnA + iB * rnB * rnB; // Compute normal impulse - float32 impulse = K > 0.0f ? - C / K : 0.0f; + float impulse = K > 0.0f ? - C / K : 0.0f; b2Vec2 P = impulse * normal; diff --git a/src/libraries/Box2D/Dynamics/b2_contact_solver.h b/src/libraries/Box2D/Dynamics/b2_contact_solver.h new file mode 100644 index 000000000..bef5e819c --- /dev/null +++ b/src/libraries/Box2D/Dynamics/b2_contact_solver.h @@ -0,0 +1,99 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_CONTACT_SOLVER_H +#define B2_CONTACT_SOLVER_H + +#include "box2d/b2_collision.h" +#include "box2d/b2_math.h" +#include "box2d/b2_time_step.h" + +class b2Contact; +class b2Body; +class b2StackAllocator; +struct b2ContactPositionConstraint; + +struct b2VelocityConstraintPoint +{ + b2Vec2 rA; + b2Vec2 rB; + float normalImpulse; + float tangentImpulse; + float normalMass; + float tangentMass; + float velocityBias; +}; + +struct b2ContactVelocityConstraint +{ + b2VelocityConstraintPoint points[b2_maxManifoldPoints]; + b2Vec2 normal; + b2Mat22 normalMass; + b2Mat22 K; + int32 indexA; + int32 indexB; + float invMassA, invMassB; + float invIA, invIB; + float friction; + float restitution; + float 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/libraries/Box2D/Dynamics/Joints/b2DistanceJoint.cpp b/src/libraries/Box2D/Dynamics/b2_distance_joint.cpp similarity index 59% rename from src/libraries/Box2D/Dynamics/Joints/b2DistanceJoint.cpp rename to src/libraries/Box2D/Dynamics/b2_distance_joint.cpp index ba2b6c009..9eea08559 100644 --- a/src/libraries/Box2D/Dynamics/Joints/b2DistanceJoint.cpp +++ b/src/libraries/Box2D/Dynamics/b2_distance_joint.cpp @@ -1,24 +1,28 @@ -/* -* 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. -*/ +// MIT License -#include -#include -#include +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_body.h" +#include "box2d/b2_distance_joint.h" +#include "box2d/b2_time_step.h" // 1-D constrained system // m (v2 - v1) = lambda @@ -35,6 +39,7 @@ // 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) { @@ -52,8 +57,9 @@ b2DistanceJoint::b2DistanceJoint(const b2DistanceJointDef* def) m_localAnchorA = def->localAnchorA; m_localAnchorB = def->localAnchorB; m_length = def->length; - m_frequencyHz = def->frequencyHz; - m_dampingRatio = def->dampingRatio; + m_stiffness = def->stiffness; + m_damping = def->damping; + m_impulse = 0.0f; m_gamma = 0.0f; m_bias = 0.0f; @@ -71,14 +77,14 @@ void b2DistanceJoint::InitVelocityConstraints(const b2SolverData& data) m_invIB = m_bodyB->m_invI; b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; + float aA = data.positions[m_indexA].a; b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; + float wA = data.velocities[m_indexA].w; b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; + float aB = data.positions[m_indexB].a; b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; + float wB = data.velocities[m_indexB].w; b2Rot qA(aA), qB(aB); @@ -87,7 +93,7 @@ void b2DistanceJoint::InitVelocityConstraints(const b2SolverData& data) m_u = cB + m_rB - cA - m_rA; // Handle singularity. - float32 length = m_u.Length(); + float length = m_u.Length(); if (length > b2_linearSlop) { m_u *= 1.0f / length; @@ -97,28 +103,21 @@ void b2DistanceJoint::InitVelocityConstraints(const b2SolverData& data) 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; + float crAu = b2Cross(m_rA, m_u); + float crBu = b2Cross(m_rB, m_u); + float 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) + if (m_stiffness > 0.0f) { - float32 C = length - m_length; + float 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; + float d = m_damping; + float k = m_stiffness; // magic formulas - float32 h = data.step.dt; + float h = data.step.dt; + + // gamma = 1 / (h * (d + h * k)), the extra factor of h in the denominator is since the lambda is an impulse, not a force 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; @@ -130,6 +129,7 @@ void b2DistanceJoint::InitVelocityConstraints(const b2SolverData& data) { m_gamma = 0.0f; m_bias = 0.0f; + m_mass = invMass != 0.0f ? 1.0f / invMass : 0.0f; } if (data.step.warmStarting) @@ -157,16 +157,16 @@ void b2DistanceJoint::InitVelocityConstraints(const b2SolverData& data) void b2DistanceJoint::SolveVelocityConstraints(const b2SolverData& data) { b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; + float wA = data.velocities[m_indexA].w; b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; + float 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); + float Cdot = b2Dot(m_u, vpB - vpA); - float32 impulse = -m_mass * (Cdot + m_bias + m_gamma * m_impulse); + float impulse = -m_mass * (Cdot + m_bias + m_gamma * m_impulse); m_impulse += impulse; b2Vec2 P = impulse * m_u; @@ -183,16 +183,16 @@ void b2DistanceJoint::SolveVelocityConstraints(const b2SolverData& data) bool b2DistanceJoint::SolvePositionConstraints(const b2SolverData& data) { - if (m_frequencyHz > 0.0f) + if (m_stiffness > 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; + float aA = data.positions[m_indexA].a; b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; + float aB = data.positions[m_indexB].a; b2Rot qA(aA), qB(aB); @@ -200,11 +200,11 @@ bool b2DistanceJoint::SolvePositionConstraints(const b2SolverData& data) b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); b2Vec2 u = cB + rB - cA - rA; - float32 length = u.Normalize(); - float32 C = length - m_length; + float length = u.Normalize(); + float C = length - m_length; C = b2Clamp(C, -b2_maxLinearCorrection, b2_maxLinearCorrection); - float32 impulse = -m_mass * C; + float impulse = -m_mass * C; b2Vec2 P = impulse * u; cA -= m_invMassA * P; @@ -230,13 +230,13 @@ b2Vec2 b2DistanceJoint::GetAnchorB() const return m_bodyB->GetWorldPoint(m_localAnchorB); } -b2Vec2 b2DistanceJoint::GetReactionForce(float32 inv_dt) const +b2Vec2 b2DistanceJoint::GetReactionForce(float inv_dt) const { b2Vec2 F = (inv_dt * m_impulse) * m_u; return F; } -float32 b2DistanceJoint::GetReactionTorque(float32 inv_dt) const +float b2DistanceJoint::GetReactionTorque(float inv_dt) const { B2_NOT_USED(inv_dt); return 0.0f; @@ -247,14 +247,14 @@ 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); + b2Dump(" b2DistanceJointDef jd;\n"); + b2Dump(" jd.bodyA = bodies[%d];\n", indexA); + b2Dump(" jd.bodyB = bodies[%d];\n", indexB); + b2Dump(" jd.collideConnected = bool(%d);\n", m_collideConnected); + b2Dump(" jd.localAnchorA.Set(%.9g, %.9g);\n", m_localAnchorA.x, m_localAnchorA.y); + b2Dump(" jd.localAnchorB.Set(%.9g, %.9g);\n", m_localAnchorB.x, m_localAnchorB.y); + b2Dump(" jd.length = %.9g;\n", m_length); + b2Dump(" jd.stiffness = %.9g;\n", m_stiffness); + b2Dump(" jd.damping = %.9g;\n", m_damping); + b2Dump(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); } diff --git a/src/libraries/Box2D/Dynamics/b2_edge_circle_contact.cpp b/src/libraries/Box2D/Dynamics/b2_edge_circle_contact.cpp new file mode 100644 index 000000000..8a126de6c --- /dev/null +++ b/src/libraries/Box2D/Dynamics/b2_edge_circle_contact.cpp @@ -0,0 +1,54 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "b2_edge_circle_contact.h" + +#include "box2d/b2_block_allocator.h" +#include "box2d/b2_fixture.h" + +#include + +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/libraries/Box2D/Dynamics/b2_edge_circle_contact.h b/src/libraries/Box2D/Dynamics/b2_edge_circle_contact.h new file mode 100644 index 000000000..3efc88e60 --- /dev/null +++ b/src/libraries/Box2D/Dynamics/b2_edge_circle_contact.h @@ -0,0 +1,43 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_EDGE_AND_CIRCLE_CONTACT_H +#define B2_EDGE_AND_CIRCLE_CONTACT_H + +#include "box2d/b2_contact.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/libraries/Box2D/Dynamics/b2_edge_polygon_contact.cpp b/src/libraries/Box2D/Dynamics/b2_edge_polygon_contact.cpp new file mode 100644 index 000000000..e617e3516 --- /dev/null +++ b/src/libraries/Box2D/Dynamics/b2_edge_polygon_contact.cpp @@ -0,0 +1,54 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "b2_edge_polygon_contact.h" + +#include "box2d/b2_block_allocator.h" +#include "box2d/b2_fixture.h" + +#include + +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/libraries/Box2D/Dynamics/b2_edge_polygon_contact.h b/src/libraries/Box2D/Dynamics/b2_edge_polygon_contact.h new file mode 100644 index 000000000..e6616b534 --- /dev/null +++ b/src/libraries/Box2D/Dynamics/b2_edge_polygon_contact.h @@ -0,0 +1,43 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_EDGE_AND_POLYGON_CONTACT_H +#define B2_EDGE_AND_POLYGON_CONTACT_H + +#include "box2d/b2_contact.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/libraries/Box2D/Dynamics/b2Fixture.cpp b/src/libraries/Box2D/Dynamics/b2_fixture.cpp similarity index 54% rename from src/libraries/Box2D/Dynamics/b2Fixture.cpp rename to src/libraries/Box2D/Dynamics/b2_fixture.cpp index fb17f0a3e..420cfdcfa 100644 --- a/src/libraries/Box2D/Dynamics/b2Fixture.cpp +++ b/src/libraries/Box2D/Dynamics/b2_fixture.cpp @@ -1,40 +1,44 @@ -/* -* 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. -*/ +// MIT License -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_fixture.h" +#include "box2d/b2_block_allocator.h" +#include "box2d/b2_broad_phase.h" +#include "box2d/b2_chain_shape.h" +#include "box2d/b2_circle_shape.h" +#include "box2d/b2_collision.h" +#include "box2d/b2_contact.h" +#include "box2d/b2_edge_shape.h" +#include "box2d/b2_polygon_shape.h" +#include "box2d/b2_world.h" b2Fixture::b2Fixture() { - m_userData = NULL; - m_body = NULL; - m_next = NULL; - m_proxies = NULL; + m_userData = nullptr; + m_body = nullptr; + m_next = nullptr; + m_proxies = nullptr; m_proxyCount = 0; - m_shape = NULL; + m_shape = nullptr; m_density = 0.0f; } @@ -45,7 +49,7 @@ void b2Fixture::Create(b2BlockAllocator* allocator, b2Body* body, const b2Fixtur m_restitution = def->restitution; m_body = body; - m_next = NULL; + m_next = nullptr; m_filter = def->filter; @@ -58,7 +62,7 @@ void b2Fixture::Create(b2BlockAllocator* allocator, b2Body* body, const b2Fixtur m_proxies = (b2FixtureProxy*)allocator->Allocate(childCount * sizeof(b2FixtureProxy)); for (int32 i = 0; i < childCount; ++i) { - m_proxies[i].fixture = NULL; + m_proxies[i].fixture = nullptr; m_proxies[i].proxyId = b2BroadPhase::e_nullProxy; } m_proxyCount = 0; @@ -74,7 +78,7 @@ void b2Fixture::Destroy(b2BlockAllocator* allocator) // Free the proxy array. int32 childCount = m_shape->GetChildCount(); allocator->Free(m_proxies, childCount * sizeof(b2FixtureProxy)); - m_proxies = NULL; + m_proxies = nullptr; // Free the child shape. switch (m_shape->m_type) @@ -116,7 +120,7 @@ void b2Fixture::Destroy(b2BlockAllocator* allocator) break; } - m_shape = NULL; + m_shape = nullptr; } void b2Fixture::CreateProxies(b2BroadPhase* broadPhase, const b2Transform& xf) @@ -167,7 +171,7 @@ void b2Fixture::Synchronize(b2BroadPhase* broadPhase, const b2Transform& transfo proxy->aabb.Combine(aabb1, aabb2); - b2Vec2 displacement = transform2.p - transform1.p; + b2Vec2 displacement = aabb2.GetCenter() - aabb1.GetCenter(); broadPhase->MoveProxy(proxy->proxyId, proxy->aabb, displacement); } @@ -182,7 +186,7 @@ void b2Fixture::SetFilterData(const b2Filter& filter) void b2Fixture::Refilter() { - if (m_body == NULL) + if (m_body == nullptr) { return; } @@ -204,7 +208,7 @@ void b2Fixture::Refilter() b2World* world = m_body->GetWorld(); - if (world == NULL) + if (world == nullptr) { return; } @@ -228,67 +232,64 @@ void b2Fixture::SetSensor(bool 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); + b2Dump(" b2FixtureDef fd;\n"); + b2Dump(" fd.friction = %.9g;\n", m_friction); + b2Dump(" fd.restitution = %.9g;\n", m_restitution); + b2Dump(" fd.density = %.9g;\n", m_density); + b2Dump(" fd.isSensor = bool(%d);\n", m_isSensor); + b2Dump(" fd.filter.categoryBits = uint16(%d);\n", m_filter.categoryBits); + b2Dump(" fd.filter.maskBits = uint16(%d);\n", m_filter.maskBits); + b2Dump(" 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); + b2Dump(" b2CircleShape shape;\n"); + b2Dump(" shape.m_radius = %.9g;\n", s->m_radius); + b2Dump(" shape.m_p.Set(%.9g, %.9g);\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); + b2Dump(" b2EdgeShape shape;\n"); + b2Dump(" shape.m_radius = %.9g;\n", s->m_radius); + b2Dump(" shape.m_vertex0.Set(%.9g, %.9g);\n", s->m_vertex0.x, s->m_vertex0.y); + b2Dump(" shape.m_vertex1.Set(%.9g, %.9g);\n", s->m_vertex1.x, s->m_vertex1.y); + b2Dump(" shape.m_vertex2.Set(%.9g, %.9g);\n", s->m_vertex2.x, s->m_vertex2.y); + b2Dump(" shape.m_vertex3.Set(%.9g, %.9g);\n", s->m_vertex3.x, s->m_vertex3.y); + b2Dump(" shape.m_oneSided = bool(%d);\n", s->m_oneSided); } break; case b2Shape::e_polygon: { b2PolygonShape* s = (b2PolygonShape*)m_shape; - b2Log(" b2PolygonShape shape;\n"); - b2Log(" b2Vec2 vs[%d];\n", b2_maxPolygonVertices); + b2Dump(" b2PolygonShape shape;\n"); + b2Dump(" 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); + b2Dump(" vs[%d].Set(%.9g, %.9g);\n", i, s->m_vertices[i].x, s->m_vertices[i].y); } - b2Log(" shape.Set(vs, %d);\n", s->m_count); + b2Dump(" 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); + b2Dump(" b2ChainShape shape;\n"); + b2Dump(" 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); + b2Dump(" vs[%d].Set(%.9g, %.9g);\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); + b2Dump(" shape.CreateChain(vs, %d);\n", s->m_count); + b2Dump(" shape.m_prevVertex.Set(%.9g, %.9g);\n", s->m_prevVertex.x, s->m_prevVertex.y); + b2Dump(" shape.m_nextVertex.Set(%.9g, %.9g);\n", s->m_nextVertex.x, s->m_nextVertex.y); } break; @@ -296,8 +297,8 @@ void b2Fixture::Dump(int32 bodyIndex) return; } - b2Log("\n"); - b2Log(" fd.shape = &shape;\n"); - b2Log("\n"); - b2Log(" bodies[%d]->CreateFixture(&fd);\n", bodyIndex); + b2Dump("\n"); + b2Dump(" fd.shape = &shape;\n"); + b2Dump("\n"); + b2Dump(" bodies[%d]->CreateFixture(&fd);\n", bodyIndex); } diff --git a/src/libraries/Box2D/Dynamics/Joints/b2FrictionJoint.cpp b/src/libraries/Box2D/Dynamics/b2_friction_joint.cpp similarity index 62% rename from src/libraries/Box2D/Dynamics/Joints/b2FrictionJoint.cpp rename to src/libraries/Box2D/Dynamics/b2_friction_joint.cpp index 412d257a7..d9d893ad3 100644 --- a/src/libraries/Box2D/Dynamics/Joints/b2FrictionJoint.cpp +++ b/src/libraries/Box2D/Dynamics/b2_friction_joint.cpp @@ -1,24 +1,28 @@ -/* -* 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. -*/ +// MIT License -#include -#include -#include +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_friction_joint.h" +#include "box2d/b2_body.h" +#include "box2d/b2_time_step.h" // Point-to-point constraint // Cdot = v2 - v1 @@ -64,13 +68,13 @@ void b2FrictionJoint::InitVelocityConstraints(const b2SolverData& data) m_invIA = m_bodyA->m_invI; m_invIB = m_bodyB->m_invI; - float32 aA = data.positions[m_indexA].a; + float aA = data.positions[m_indexA].a; b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; + float wA = data.velocities[m_indexA].w; - float32 aB = data.positions[m_indexB].a; + float aB = data.positions[m_indexB].a; b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; + float wB = data.velocities[m_indexB].w; b2Rot qA(aA), qB(aB); @@ -87,8 +91,8 @@ void b2FrictionJoint::InitVelocityConstraints(const b2SolverData& data) // [ -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; + float mA = m_invMassA, mB = m_invMassB; + float 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; @@ -131,22 +135,22 @@ void b2FrictionJoint::InitVelocityConstraints(const b2SolverData& data) void b2FrictionJoint::SolveVelocityConstraints(const b2SolverData& data) { b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; + float wA = data.velocities[m_indexA].w; b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; + float wB = data.velocities[m_indexB].w; - float32 mA = m_invMassA, mB = m_invMassB; - float32 iA = m_invIA, iB = m_invIB; + float mA = m_invMassA, mB = m_invMassB; + float iA = m_invIA, iB = m_invIB; - float32 h = data.step.dt; + float h = data.step.dt; // Solve angular friction { - float32 Cdot = wB - wA; - float32 impulse = -m_angularMass * Cdot; + float Cdot = wB - wA; + float impulse = -m_angularMass * Cdot; - float32 oldImpulse = m_angularImpulse; - float32 maxImpulse = h * m_maxTorque; + float oldImpulse = m_angularImpulse; + float maxImpulse = h * m_maxTorque; m_angularImpulse = b2Clamp(m_angularImpulse + impulse, -maxImpulse, maxImpulse); impulse = m_angularImpulse - oldImpulse; @@ -162,7 +166,7 @@ void b2FrictionJoint::SolveVelocityConstraints(const b2SolverData& data) b2Vec2 oldImpulse = m_linearImpulse; m_linearImpulse += impulse; - float32 maxImpulse = h * m_maxForce; + float maxImpulse = h * m_maxForce; if (m_linearImpulse.LengthSquared() > maxImpulse * maxImpulse) { @@ -202,34 +206,34 @@ b2Vec2 b2FrictionJoint::GetAnchorB() const return m_bodyB->GetWorldPoint(m_localAnchorB); } -b2Vec2 b2FrictionJoint::GetReactionForce(float32 inv_dt) const +b2Vec2 b2FrictionJoint::GetReactionForce(float inv_dt) const { return inv_dt * m_linearImpulse; } -float32 b2FrictionJoint::GetReactionTorque(float32 inv_dt) const +float b2FrictionJoint::GetReactionTorque(float inv_dt) const { return inv_dt * m_angularImpulse; } -void b2FrictionJoint::SetMaxForce(float32 force) +void b2FrictionJoint::SetMaxForce(float force) { b2Assert(b2IsValid(force) && force >= 0.0f); m_maxForce = force; } -float32 b2FrictionJoint::GetMaxForce() const +float b2FrictionJoint::GetMaxForce() const { return m_maxForce; } -void b2FrictionJoint::SetMaxTorque(float32 torque) +void b2FrictionJoint::SetMaxTorque(float torque) { b2Assert(b2IsValid(torque) && torque >= 0.0f); m_maxTorque = torque; } -float32 b2FrictionJoint::GetMaxTorque() const +float b2FrictionJoint::GetMaxTorque() const { return m_maxTorque; } @@ -239,13 +243,13 @@ 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); + b2Dump(" b2FrictionJointDef jd;\n"); + b2Dump(" jd.bodyA = bodies[%d];\n", indexA); + b2Dump(" jd.bodyB = bodies[%d];\n", indexB); + b2Dump(" jd.collideConnected = bool(%d);\n", m_collideConnected); + b2Dump(" jd.localAnchorA.Set(%.9g, %.9g);\n", m_localAnchorA.x, m_localAnchorA.y); + b2Dump(" jd.localAnchorB.Set(%.9g, %.9g);\n", m_localAnchorB.x, m_localAnchorB.y); + b2Dump(" jd.maxForce = %.9g;\n", m_maxForce); + b2Dump(" jd.maxTorque = %.9g;\n", m_maxTorque); + b2Dump(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); } diff --git a/src/libraries/Box2D/Dynamics/Joints/b2GearJoint.cpp b/src/libraries/Box2D/Dynamics/b2_gear_joint.cpp similarity index 74% rename from src/libraries/Box2D/Dynamics/Joints/b2GearJoint.cpp rename to src/libraries/Box2D/Dynamics/b2_gear_joint.cpp index 155eb0c1d..414291093 100644 --- a/src/libraries/Box2D/Dynamics/Joints/b2GearJoint.cpp +++ b/src/libraries/Box2D/Dynamics/b2_gear_joint.cpp @@ -1,26 +1,30 @@ -/* -* 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. -*/ +// MIT License -#include -#include -#include -#include -#include +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_gear_joint.h" +#include "box2d/b2_revolute_joint.h" +#include "box2d/b2_prismatic_joint.h" +#include "box2d/b2_body.h" +#include "box2d/b2_time_step.h" // Gear Joint: // C0 = (coordinate1 + ratio * coordinate2)_initial @@ -53,7 +57,7 @@ b2GearJoint::b2GearJoint(const b2GearJointDef* def) b2Assert(m_typeA == e_revoluteJoint || m_typeA == e_prismaticJoint); b2Assert(m_typeB == e_revoluteJoint || m_typeB == e_prismaticJoint); - float32 coordinateA, coordinateB; + float coordinateA, coordinateB; // TODO_ERIN there might be some problem with the joint edges in b2Joint. @@ -62,9 +66,9 @@ b2GearJoint::b2GearJoint(const b2GearJointDef* def) // Get geometry of joint1 b2Transform xfA = m_bodyA->m_xf; - float32 aA = m_bodyA->m_sweep.a; + float aA = m_bodyA->m_sweep.a; b2Transform xfC = m_bodyC->m_xf; - float32 aC = m_bodyC->m_sweep.a; + float aC = m_bodyC->m_sweep.a; if (m_typeA == e_revoluteJoint) { @@ -94,9 +98,9 @@ b2GearJoint::b2GearJoint(const b2GearJointDef* def) // Get geometry of joint2 b2Transform xfB = m_bodyB->m_xf; - float32 aB = m_bodyB->m_sweep.a; + float aB = m_bodyB->m_sweep.a; b2Transform xfD = m_bodyD->m_xf; - float32 aD = m_bodyD->m_sweep.a; + float aD = m_bodyD->m_sweep.a; if (m_typeB == e_revoluteJoint) { @@ -147,21 +151,21 @@ void b2GearJoint::InitVelocityConstraints(const b2SolverData& data) m_iC = m_bodyC->m_invI; m_iD = m_bodyD->m_invI; - float32 aA = data.positions[m_indexA].a; + float aA = data.positions[m_indexA].a; b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; + float wA = data.velocities[m_indexA].w; - float32 aB = data.positions[m_indexB].a; + float aB = data.positions[m_indexB].a; b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; + float wB = data.velocities[m_indexB].w; - float32 aC = data.positions[m_indexC].a; + float aC = data.positions[m_indexC].a; b2Vec2 vC = data.velocities[m_indexC].v; - float32 wC = data.velocities[m_indexC].w; + float wC = data.velocities[m_indexC].w; - float32 aD = data.positions[m_indexD].a; + float aD = data.positions[m_indexD].a; b2Vec2 vD = data.velocities[m_indexD].v; - float32 wD = data.velocities[m_indexD].w; + float wD = data.velocities[m_indexD].w; b2Rot qA(aA), qB(aB), qC(aC), qD(aD); @@ -235,18 +239,18 @@ void b2GearJoint::InitVelocityConstraints(const b2SolverData& data) void b2GearJoint::SolveVelocityConstraints(const b2SolverData& data) { b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; + float wA = data.velocities[m_indexA].w; b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; + float wB = data.velocities[m_indexB].w; b2Vec2 vC = data.velocities[m_indexC].v; - float32 wC = data.velocities[m_indexC].w; + float wC = data.velocities[m_indexC].w; b2Vec2 vD = data.velocities[m_indexD].v; - float32 wD = data.velocities[m_indexD].w; + float wD = data.velocities[m_indexD].w; - float32 Cdot = b2Dot(m_JvAC, vA - vC) + b2Dot(m_JvBD, vB - vD); + float 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; + float impulse = -m_mass * Cdot; m_impulse += impulse; vA += (m_mA * impulse) * m_JvAC; @@ -271,23 +275,23 @@ void b2GearJoint::SolveVelocityConstraints(const b2SolverData& data) bool b2GearJoint::SolvePositionConstraints(const b2SolverData& data) { b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; + float aA = data.positions[m_indexA].a; b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; + float aB = data.positions[m_indexB].a; b2Vec2 cC = data.positions[m_indexC].c; - float32 aC = data.positions[m_indexC].a; + float aC = data.positions[m_indexC].a; b2Vec2 cD = data.positions[m_indexD].c; - float32 aD = data.positions[m_indexD].a; + float aD = data.positions[m_indexD].a; b2Rot qA(aA), qB(aB), qC(aC), qD(aD); - float32 linearError = 0.0f; + float linearError = 0.0f; - float32 coordinateA, coordinateB; + float coordinateA, coordinateB; b2Vec2 JvAC, JvBD; - float32 JwA, JwB, JwC, JwD; - float32 mass = 0.0f; + float JwA, JwB, JwC, JwD; + float mass = 0.0f; if (m_typeA == e_revoluteJoint) { @@ -337,9 +341,9 @@ bool b2GearJoint::SolvePositionConstraints(const b2SolverData& data) coordinateB = b2Dot(pB - pD, m_localAxisD); } - float32 C = (coordinateA + m_ratio * coordinateB) - m_constant; + float C = (coordinateA + m_ratio * coordinateB) - m_constant; - float32 impulse = 0.0f; + float impulse = 0.0f; if (mass > 0.0f) { impulse = -C / mass; @@ -377,25 +381,25 @@ b2Vec2 b2GearJoint::GetAnchorB() const return m_bodyB->GetWorldPoint(m_localAnchorB); } -b2Vec2 b2GearJoint::GetReactionForce(float32 inv_dt) const +b2Vec2 b2GearJoint::GetReactionForce(float inv_dt) const { b2Vec2 P = m_impulse * m_JvAC; return inv_dt * P; } -float32 b2GearJoint::GetReactionTorque(float32 inv_dt) const +float b2GearJoint::GetReactionTorque(float inv_dt) const { - float32 L = m_impulse * m_JwA; + float L = m_impulse * m_JwA; return inv_dt * L; } -void b2GearJoint::SetRatio(float32 ratio) +void b2GearJoint::SetRatio(float ratio) { b2Assert(b2IsValid(ratio)); m_ratio = ratio; } -float32 b2GearJoint::GetRatio() const +float b2GearJoint::GetRatio() const { return m_ratio; } @@ -408,12 +412,12 @@ void b2GearJoint::Dump() 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); + b2Dump(" b2GearJointDef jd;\n"); + b2Dump(" jd.bodyA = bodies[%d];\n", indexA); + b2Dump(" jd.bodyB = bodies[%d];\n", indexB); + b2Dump(" jd.collideConnected = bool(%d);\n", m_collideConnected); + b2Dump(" jd.joint1 = joints[%d];\n", index1); + b2Dump(" jd.joint2 = joints[%d];\n", index2); + b2Dump(" jd.ratio = %.9g;\n", m_ratio); + b2Dump(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); } diff --git a/src/libraries/Box2D/Dynamics/b2Island.cpp b/src/libraries/Box2D/Dynamics/b2_island.cpp similarity index 86% rename from src/libraries/Box2D/Dynamics/b2Island.cpp rename to src/libraries/Box2D/Dynamics/b2_island.cpp index d46589dee..48d89a850 100644 --- a/src/libraries/Box2D/Dynamics/b2Island.cpp +++ b/src/libraries/Box2D/Dynamics/b2_island.cpp @@ -1,31 +1,36 @@ -/* -* 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. -*/ +// MIT License -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_body.h" +#include "box2d/b2_contact.h" +#include "box2d/b2_distance.h" +#include "box2d/b2_fixture.h" +#include "box2d/b2_joint.h" +#include "box2d/b2_stack_allocator.h" +#include "box2d/b2_timer.h" +#include "box2d/b2_world.h" + +#include "b2_island.h" +#include "dynamics/b2_contact_solver.h" /* Position Correction Notes @@ -184,7 +189,7 @@ void b2Island::Solve(b2Profile* profile, const b2TimeStep& step, const b2Vec2& g { b2Timer timer; - float32 h = step.dt; + float h = step.dt; // Integrate velocities and apply damping. Initialize the body state. for (int32 i = 0; i < m_bodyCount; ++i) @@ -192,9 +197,9 @@ void b2Island::Solve(b2Profile* profile, const b2TimeStep& step, const b2Vec2& g b2Body* b = m_bodies[i]; b2Vec2 c = b->m_sweep.c; - float32 a = b->m_sweep.a; + float a = b->m_sweep.a; b2Vec2 v = b->m_linearVelocity; - float32 w = b->m_angularVelocity; + float w = b->m_angularVelocity; // Store positions for continuous collision. b->m_sweep.c0 = b->m_sweep.c; @@ -203,7 +208,7 @@ void b2Island::Solve(b2Profile* profile, const b2TimeStep& step, const b2Vec2& g if (b->m_type == b2_dynamicBody) { // Integrate velocities. - v += h * (b->m_gravityScale * gravity + b->m_invMass * b->m_force); + v += h * b->m_invMass * (b->m_gravityScale * b->m_mass * gravity + b->m_force); w += h * b->m_invI * b->m_torque; // Apply damping. @@ -275,22 +280,22 @@ void b2Island::Solve(b2Profile* profile, const b2TimeStep& step, const b2Vec2& g for (int32 i = 0; i < m_bodyCount; ++i) { b2Vec2 c = m_positions[i].c; - float32 a = m_positions[i].a; + float a = m_positions[i].a; b2Vec2 v = m_velocities[i].v; - float32 w = m_velocities[i].w; + float 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(); + float ratio = b2_maxTranslation / translation.Length(); v *= ratio; } - float32 rotation = h * w; + float rotation = h * w; if (rotation * rotation > b2_maxRotationSquared) { - float32 ratio = b2_maxRotation / b2Abs(rotation); + float ratio = b2_maxRotation / b2Abs(rotation); w *= ratio; } @@ -312,9 +317,9 @@ void b2Island::Solve(b2Profile* profile, const b2TimeStep& step, const b2Vec2& g bool contactsOkay = contactSolver.SolvePositionConstraints(); bool jointsOkay = true; - for (int32 i = 0; i < m_jointCount; ++i) + for (int32 j = 0; j < m_jointCount; ++j) { - bool jointOkay = m_joints[i]->SolvePositionConstraints(solverData); + bool jointOkay = m_joints[j]->SolvePositionConstraints(solverData); jointsOkay = jointsOkay && jointOkay; } @@ -343,10 +348,10 @@ void b2Island::Solve(b2Profile* profile, const b2TimeStep& step, const b2Vec2& g if (allowSleep) { - float32 minSleepTime = b2_maxFloat; + float minSleepTime = b2_maxFloat; - const float32 linTolSqr = b2_linearSleepTolerance * b2_linearSleepTolerance; - const float32 angTolSqr = b2_angularSleepTolerance * b2_angularSleepTolerance; + const float linTolSqr = b2_linearSleepTolerance * b2_linearSleepTolerance; + const float angTolSqr = b2_angularSleepTolerance * b2_angularSleepTolerance; for (int32 i = 0; i < m_bodyCount; ++i) { @@ -467,28 +472,28 @@ void b2Island::SolveTOI(const b2TimeStep& subStep, int32 toiIndexA, int32 toiInd // Don't store the TOI contact forces for warm starting // because they can be quite large. - float32 h = subStep.dt; + float 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; + float a = m_positions[i].a; b2Vec2 v = m_velocities[i].v; - float32 w = m_velocities[i].w; + float 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(); + float ratio = b2_maxTranslation / translation.Length(); v *= ratio; } - float32 rotation = h * w; + float rotation = h * w; if (rotation * rotation > b2_maxRotationSquared) { - float32 ratio = b2_maxRotation / b2Abs(rotation); + float ratio = b2_maxRotation / b2Abs(rotation); w *= ratio; } @@ -515,7 +520,7 @@ void b2Island::SolveTOI(const b2TimeStep& subStep, int32 toiIndexA, int32 toiInd void b2Island::Report(const b2ContactVelocityConstraint* constraints) { - if (m_listener == NULL) + if (m_listener == nullptr) { return; } diff --git a/src/libraries/Box2D/Dynamics/b2Island.h b/src/libraries/Box2D/Dynamics/b2_island.h similarity index 54% rename from src/libraries/Box2D/Dynamics/b2Island.h rename to src/libraries/Box2D/Dynamics/b2_island.h index 4a814c463..2e28a357b 100644 --- a/src/libraries/Box2D/Dynamics/b2Island.h +++ b/src/libraries/Box2D/Dynamics/b2_island.h @@ -1,27 +1,31 @@ -/* -* 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. -*/ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_ISLAND_H #define B2_ISLAND_H -#include -#include -#include +#include "box2d/b2_body.h" +#include "box2d/b2_math.h" +#include "box2d/b2_time_step.h" class b2Contact; class b2Joint; diff --git a/src/libraries/Box2D/Dynamics/b2_joint.cpp b/src/libraries/Box2D/Dynamics/b2_joint.cpp new file mode 100644 index 000000000..1f8ac2644 --- /dev/null +++ b/src/libraries/Box2D/Dynamics/b2_joint.cpp @@ -0,0 +1,313 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_block_allocator.h" +#include "box2d/b2_body.h" +#include "box2d/b2_distance_joint.h" +#include "box2d/b2_draw.h" +#include "box2d/b2_friction_joint.h" +#include "box2d/b2_gear_joint.h" +#include "box2d/b2_motor_joint.h" +#include "box2d/b2_mouse_joint.h" +#include "box2d/b2_prismatic_joint.h" +#include "box2d/b2_pulley_joint.h" +#include "box2d/b2_revolute_joint.h" +#include "box2d/b2_rope_joint.h" +#include "box2d/b2_weld_joint.h" +#include "box2d/b2_wheel_joint.h" +#include "box2d/b2_world.h" + +#include + +void b2LinearStiffness(float& stiffness, float& damping, + float frequencyHertz, float dampingRatio, + const b2Body* bodyA, const b2Body* bodyB) +{ + float massA = bodyA->GetMass(); + float massB = bodyB->GetMass(); + float mass; + if (massA > 0.0f && massB > 0.0f) + { + mass = massA * massB / (massA + massB); + } + else if (massA > 0.0f) + { + mass = massA; + } + else + { + mass = massB; + } + + float omega = 2.0f * b2_pi * frequencyHertz; + stiffness = mass * omega * omega; + damping = 2.0f * mass * dampingRatio * omega; +} + +void b2AngularStiffness(float& stiffness, float& damping, + float frequencyHertz, float dampingRatio, + const b2Body* bodyA, const b2Body* bodyB) +{ + float IA = bodyA->GetInertia(); + float IB = bodyB->GetInertia(); + float I; + if (IA > 0.0f && IB > 0.0f) + { + I = IA * IB / (IA + IB); + } + else if (IA > 0.0f) + { + I = IA; + } + else + { + I = IB; + } + + float omega = 2.0f * b2_pi * frequencyHertz; + stiffness = I * omega * omega; + damping = 2.0f * I * dampingRatio * omega; +} + +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(def)); + } + break; + + case e_mouseJoint: + { + void* mem = allocator->Allocate(sizeof(b2MouseJoint)); + joint = new (mem) b2MouseJoint(static_cast(def)); + } + break; + + case e_prismaticJoint: + { + void* mem = allocator->Allocate(sizeof(b2PrismaticJoint)); + joint = new (mem) b2PrismaticJoint(static_cast(def)); + } + break; + + case e_revoluteJoint: + { + void* mem = allocator->Allocate(sizeof(b2RevoluteJoint)); + joint = new (mem) b2RevoluteJoint(static_cast(def)); + } + break; + + case e_pulleyJoint: + { + void* mem = allocator->Allocate(sizeof(b2PulleyJoint)); + joint = new (mem) b2PulleyJoint(static_cast(def)); + } + break; + + case e_gearJoint: + { + void* mem = allocator->Allocate(sizeof(b2GearJoint)); + joint = new (mem) b2GearJoint(static_cast(def)); + } + break; + + case e_wheelJoint: + { + void* mem = allocator->Allocate(sizeof(b2WheelJoint)); + joint = new (mem) b2WheelJoint(static_cast(def)); + } + break; + + case e_weldJoint: + { + void* mem = allocator->Allocate(sizeof(b2WeldJoint)); + joint = new (mem) b2WeldJoint(static_cast(def)); + } + break; + + case e_frictionJoint: + { + void* mem = allocator->Allocate(sizeof(b2FrictionJoint)); + joint = new (mem) b2FrictionJoint(static_cast(def)); + } + break; + + case e_ropeJoint: + { + void* mem = allocator->Allocate(sizeof(b2RopeJoint)); + joint = new (mem) b2RopeJoint(static_cast(def)); + } + break; + + case e_motorJoint: + { + void* mem = allocator->Allocate(sizeof(b2MotorJoint)); + joint = new (mem) b2MotorJoint(static_cast(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::IsEnabled() const +{ + return m_bodyA->IsEnabled() && m_bodyB->IsEnabled(); +} + +void b2Joint::Draw(b2Draw* draw) const +{ + const b2Transform& xf1 = m_bodyA->GetTransform(); + const b2Transform& xf2 = m_bodyB->GetTransform(); + b2Vec2 x1 = xf1.p; + b2Vec2 x2 = xf2.p; + b2Vec2 p1 = GetAnchorA(); + b2Vec2 p2 = GetAnchorB(); + + b2Color color(0.5f, 0.8f, 0.8f); + + switch (m_type) + { + case e_distanceJoint: + draw->DrawSegment(p1, p2, color); + break; + + case e_pulleyJoint: + { + b2PulleyJoint* pulley = (b2PulleyJoint*)this; + b2Vec2 s1 = pulley->GetGroundAnchorA(); + b2Vec2 s2 = pulley->GetGroundAnchorB(); + draw->DrawSegment(s1, p1, color); + draw->DrawSegment(s2, p2, color); + draw->DrawSegment(s1, s2, color); + } + break; + + case e_mouseJoint: + { + b2Color c; + c.Set(0.0f, 1.0f, 0.0f); + draw->DrawPoint(p1, 4.0f, c); + draw->DrawPoint(p2, 4.0f, c); + + c.Set(0.8f, 0.8f, 0.8f); + draw->DrawSegment(p1, p2, c); + + } + break; + + default: + draw->DrawSegment(x1, p1, color); + draw->DrawSegment(p1, p2, color); + draw->DrawSegment(x2, p2, color); + } +} diff --git a/src/libraries/Box2D/Dynamics/Joints/b2MotorJoint.cpp b/src/libraries/Box2D/Dynamics/b2_motor_joint.cpp similarity index 61% rename from src/libraries/Box2D/Dynamics/Joints/b2MotorJoint.cpp rename to src/libraries/Box2D/Dynamics/b2_motor_joint.cpp index e5bbcb165..6e0b07538 100644 --- a/src/libraries/Box2D/Dynamics/Joints/b2MotorJoint.cpp +++ b/src/libraries/Box2D/Dynamics/b2_motor_joint.cpp @@ -1,24 +1,28 @@ -/* -* 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. -*/ +// MIT License -#include -#include -#include +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_body.h" +#include "box2d/b2_motor_joint.h" +#include "box2d/b2_time_step.h" // Point-to-point constraint // Cdot = v2 - v1 @@ -26,6 +30,9 @@ // 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 @@ -39,8 +46,8 @@ void b2MotorJointDef::Initialize(b2Body* bA, b2Body* bB) b2Vec2 xB = bodyB->GetPosition(); linearOffset = bodyA->GetLocalPoint(xB); - float32 angleA = bodyA->GetAngle(); - float32 angleB = bodyB->GetAngle(); + float angleA = bodyA->GetAngle(); + float angleB = bodyB->GetAngle(); angularOffset = angleB - angleA; } @@ -70,23 +77,22 @@ void b2MotorJoint::InitVelocityConstraints(const b2SolverData& data) m_invIB = m_bodyB->m_invI; b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; + float aA = data.positions[m_indexA].a; b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; + float wA = data.velocities[m_indexA].w; b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; + float aB = data.positions[m_indexB].a; b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; + float wB = data.velocities[m_indexB].w; b2Rot qA(aA), qB(aB); // Compute the effective mass matrix. - m_rA = b2Mul(qA, -m_localCenterA); + m_rA = b2Mul(qA, m_linearOffset - m_localCenterA); m_rB = b2Mul(qB, -m_localCenterB); // J = [-I -r1_skew I r2_skew] - // [ 0 -1 0 1] // r_skew = [-ry; rx] // Matlab @@ -94,9 +100,10 @@ void b2MotorJoint::InitVelocityConstraints(const b2SolverData& data) // [ -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; + float mA = m_invMassA, mB = m_invMassB; + float 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; @@ -111,7 +118,7 @@ void b2MotorJoint::InitVelocityConstraints(const b2SolverData& data) m_angularMass = 1.0f / m_angularMass; } - m_linearError = cB + m_rB - cA - m_rA - b2Mul(qA, m_linearOffset); + m_linearError = cB + m_rB - cA - m_rA; m_angularError = aB - aA - m_angularOffset; if (data.step.warmStarting) @@ -141,23 +148,23 @@ void b2MotorJoint::InitVelocityConstraints(const b2SolverData& data) void b2MotorJoint::SolveVelocityConstraints(const b2SolverData& data) { b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; + float wA = data.velocities[m_indexA].w; b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; + float wB = data.velocities[m_indexB].w; - float32 mA = m_invMassA, mB = m_invMassB; - float32 iA = m_invIA, iB = m_invIB; + float mA = m_invMassA, mB = m_invMassB; + float iA = m_invIA, iB = m_invIB; - float32 h = data.step.dt; - float32 inv_h = data.step.inv_dt; + float h = data.step.dt; + float inv_h = data.step.inv_dt; // Solve angular friction { - float32 Cdot = wB - wA + inv_h * m_correctionFactor * m_angularError; - float32 impulse = -m_angularMass * Cdot; + float Cdot = wB - wA + inv_h * m_correctionFactor * m_angularError; + float impulse = -m_angularMass * Cdot; - float32 oldImpulse = m_angularImpulse; - float32 maxImpulse = h * m_maxTorque; + float oldImpulse = m_angularImpulse; + float maxImpulse = h * m_maxTorque; m_angularImpulse = b2Clamp(m_angularImpulse + impulse, -maxImpulse, maxImpulse); impulse = m_angularImpulse - oldImpulse; @@ -173,7 +180,7 @@ void b2MotorJoint::SolveVelocityConstraints(const b2SolverData& data) b2Vec2 oldImpulse = m_linearImpulse; m_linearImpulse += impulse; - float32 maxImpulse = h * m_maxForce; + float maxImpulse = h * m_maxForce; if (m_linearImpulse.LengthSquared() > maxImpulse * maxImpulse) { @@ -213,45 +220,45 @@ b2Vec2 b2MotorJoint::GetAnchorB() const return m_bodyB->GetPosition(); } -b2Vec2 b2MotorJoint::GetReactionForce(float32 inv_dt) const +b2Vec2 b2MotorJoint::GetReactionForce(float inv_dt) const { return inv_dt * m_linearImpulse; } -float32 b2MotorJoint::GetReactionTorque(float32 inv_dt) const +float b2MotorJoint::GetReactionTorque(float inv_dt) const { return inv_dt * m_angularImpulse; } -void b2MotorJoint::SetMaxForce(float32 force) +void b2MotorJoint::SetMaxForce(float force) { b2Assert(b2IsValid(force) && force >= 0.0f); m_maxForce = force; } -float32 b2MotorJoint::GetMaxForce() const +float b2MotorJoint::GetMaxForce() const { return m_maxForce; } -void b2MotorJoint::SetMaxTorque(float32 torque) +void b2MotorJoint::SetMaxTorque(float torque) { b2Assert(b2IsValid(torque) && torque >= 0.0f); m_maxTorque = torque; } -float32 b2MotorJoint::GetMaxTorque() const +float b2MotorJoint::GetMaxTorque() const { return m_maxTorque; } -void b2MotorJoint::SetCorrectionFactor(float32 factor) +void b2MotorJoint::SetCorrectionFactor(float factor) { b2Assert(b2IsValid(factor) && 0.0f <= factor && factor <= 1.0f); m_correctionFactor = factor; } -float32 b2MotorJoint::GetCorrectionFactor() const +float b2MotorJoint::GetCorrectionFactor() const { return m_correctionFactor; } @@ -271,7 +278,7 @@ const b2Vec2& b2MotorJoint::GetLinearOffset() const return m_linearOffset; } -void b2MotorJoint::SetAngularOffset(float32 angularOffset) +void b2MotorJoint::SetAngularOffset(float angularOffset) { if (angularOffset != m_angularOffset) { @@ -281,7 +288,7 @@ void b2MotorJoint::SetAngularOffset(float32 angularOffset) } } -float32 b2MotorJoint::GetAngularOffset() const +float b2MotorJoint::GetAngularOffset() const { return m_angularOffset; } @@ -291,14 +298,14 @@ 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); + b2Dump(" b2MotorJointDef jd;\n"); + b2Dump(" jd.bodyA = bodies[%d];\n", indexA); + b2Dump(" jd.bodyB = bodies[%d];\n", indexB); + b2Dump(" jd.collideConnected = bool(%d);\n", m_collideConnected); + b2Dump(" jd.linearOffset.Set(%.9g, %.9g);\n", m_linearOffset.x, m_linearOffset.y); + b2Dump(" jd.angularOffset = %.9g;\n", m_angularOffset); + b2Dump(" jd.maxForce = %.9g;\n", m_maxForce); + b2Dump(" jd.maxTorque = %.9g;\n", m_maxTorque); + b2Dump(" jd.correctionFactor = %.9g;\n", m_correctionFactor); + b2Dump(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); } diff --git a/src/libraries/Box2D/Dynamics/Joints/b2MouseJoint.cpp b/src/libraries/Box2D/Dynamics/b2_mouse_joint.cpp similarity index 56% rename from src/libraries/Box2D/Dynamics/Joints/b2MouseJoint.cpp rename to src/libraries/Box2D/Dynamics/b2_mouse_joint.cpp index ea96edde9..1ea6dd420 100644 --- a/src/libraries/Box2D/Dynamics/Joints/b2MouseJoint.cpp +++ b/src/libraries/Box2D/Dynamics/b2_mouse_joint.cpp @@ -1,24 +1,28 @@ -/* -* 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. -*/ +// MIT License -#include -#include -#include +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_body.h" +#include "box2d/b2_mouse_joint.h" +#include "box2d/b2_time_step.h" // p = attached point, m = mouse point // C = p - m @@ -31,31 +35,24 @@ 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_stiffness = def->stiffness; + m_damping = def->damping; + 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 (m_bodyB->IsAwake() == false) + if (target != m_targetA) { m_bodyB->SetAwake(true); + m_targetA = target; } - m_targetA = target; } const b2Vec2& b2MouseJoint::GetTarget() const @@ -63,36 +60,16 @@ const b2Vec2& b2MouseJoint::GetTarget() const return m_targetA; } -void b2MouseJoint::SetMaxForce(float32 force) +void b2MouseJoint::SetMaxForce(float force) { m_maxForce = force; } -float32 b2MouseJoint::GetMaxForce() const +float 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; @@ -101,28 +78,21 @@ void b2MouseJoint::InitVelocityConstraints(const b2SolverData& data) m_invIB = m_bodyB->m_invI; b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; + float aB = data.positions[m_indexB].a; b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; + float wB = data.velocities[m_indexB].w; b2Rot qB(aB); - float32 mass = m_bodyB->GetMass(); + float 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); + float d = m_damping; + float k = m_stiffness; // 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); + float h = data.step.dt; m_gamma = h * (d + h * k); if (m_gamma != 0.0f) { @@ -168,7 +138,7 @@ void b2MouseJoint::InitVelocityConstraints(const b2SolverData& data) void b2MouseJoint::SolveVelocityConstraints(const b2SolverData& data) { b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; + float wB = data.velocities[m_indexB].w; // Cdot = v + cross(w, r) b2Vec2 Cdot = vB + b2Cross(wB, m_rB); @@ -176,7 +146,7 @@ void b2MouseJoint::SolveVelocityConstraints(const b2SolverData& data) b2Vec2 oldImpulse = m_impulse; m_impulse += impulse; - float32 maxImpulse = data.step.dt * m_maxForce; + float maxImpulse = data.step.dt * m_maxForce; if (m_impulse.LengthSquared() > maxImpulse * maxImpulse) { m_impulse *= maxImpulse / m_impulse.Length(); @@ -206,12 +176,12 @@ b2Vec2 b2MouseJoint::GetAnchorB() const return m_bodyB->GetWorldPoint(m_localAnchorB); } -b2Vec2 b2MouseJoint::GetReactionForce(float32 inv_dt) const +b2Vec2 b2MouseJoint::GetReactionForce(float inv_dt) const { return inv_dt * m_impulse; } -float32 b2MouseJoint::GetReactionTorque(float32 inv_dt) const +float b2MouseJoint::GetReactionTorque(float inv_dt) const { return inv_dt * 0.0f; } diff --git a/src/libraries/Box2D/Dynamics/b2_polygon_circle_contact.cpp b/src/libraries/Box2D/Dynamics/b2_polygon_circle_contact.cpp new file mode 100644 index 000000000..e4f34f582 --- /dev/null +++ b/src/libraries/Box2D/Dynamics/b2_polygon_circle_contact.cpp @@ -0,0 +1,54 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "b2_polygon_circle_contact.h" + +#include "box2d/b2_block_allocator.h" +#include "box2d/b2_fixture.h" + +#include + +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/libraries/Box2D/Dynamics/b2_polygon_circle_contact.h b/src/libraries/Box2D/Dynamics/b2_polygon_circle_contact.h new file mode 100644 index 000000000..6ae542510 --- /dev/null +++ b/src/libraries/Box2D/Dynamics/b2_polygon_circle_contact.h @@ -0,0 +1,42 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_POLYGON_AND_CIRCLE_CONTACT_H +#define B2_POLYGON_AND_CIRCLE_CONTACT_H + +#include "box2d/b2_contact.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/libraries/Box2D/Dynamics/b2_polygon_contact.cpp b/src/libraries/Box2D/Dynamics/b2_polygon_contact.cpp new file mode 100644 index 000000000..e92a9e806 --- /dev/null +++ b/src/libraries/Box2D/Dynamics/b2_polygon_contact.cpp @@ -0,0 +1,57 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "b2_polygon_contact.h" + +#include "box2d/b2_block_allocator.h" +#include "box2d/b2_body.h" +#include "box2d/b2_fixture.h" +#include "box2d/b2_time_of_impact.h" +#include "box2d/b2_world_callbacks.h" + +#include + +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/libraries/Box2D/Dynamics/b2_polygon_contact.h b/src/libraries/Box2D/Dynamics/b2_polygon_contact.h new file mode 100644 index 000000000..0516cb0ec --- /dev/null +++ b/src/libraries/Box2D/Dynamics/b2_polygon_contact.h @@ -0,0 +1,43 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_POLYGON_CONTACT_H +#define B2_POLYGON_CONTACT_H + +#include "box2d/b2_contact.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/libraries/Box2D/Dynamics/b2_prismatic_joint.cpp b/src/libraries/Box2D/Dynamics/b2_prismatic_joint.cpp new file mode 100644 index 000000000..cb550170f --- /dev/null +++ b/src/libraries/Box2D/Dynamics/b2_prismatic_joint.cpp @@ -0,0 +1,644 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_body.h" +#include "box2d/b2_draw.h" +#include "box2d/b2_prismatic_joint.h" +#include "box2d/b2_time_step.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)] + +// Predictive limit is applied even when the limit is not active. +// Prevents a constraint speed that can lead to a constraint error in one time step. +// Want C2 = C1 + h * Cdot >= 0 +// Or: +// Cdot + C1/h >= 0 +// I do not apply a negative constraint error because that is handled in position correction. +// So: +// Cdot + max(C1, 0)/h >= 0 + +// Block Solver +// We develop a block solver that includes the angular and linear constraints. This makes the limit stiffer. +// +// The Jacobian has 2 rows: +// J = [-uT -s1 uT s2] // linear +// [0 -1 0 1] // angular +// +// u = perp +// s1 = cross(d + r1, u), s2 = cross(r2, u) +// a1 = cross(d + r1, v), a2 = cross(r2, v) + +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_axialMass = 0.0f; + m_motorImpulse = 0.0f; + m_lowerImpulse = 0.0f; + m_upperImpulse = 0.0f; + + m_lowerTranslation = def->lowerTranslation; + m_upperTranslation = def->upperTranslation; + + b2Assert(m_lowerTranslation <= m_upperTranslation); + + m_maxMotorForce = def->maxMotorForce; + m_motorSpeed = def->motorSpeed; + m_enableLimit = def->enableLimit; + m_enableMotor = def->enableMotor; + + m_translation = 0.0f; + 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; + float aA = data.positions[m_indexA].a; + b2Vec2 vA = data.velocities[m_indexA].v; + float wA = data.velocities[m_indexA].w; + + b2Vec2 cB = data.positions[m_indexB].c; + float aB = data.positions[m_indexB].a; + b2Vec2 vB = data.velocities[m_indexB].v; + float 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; + + float mA = m_invMassA, mB = m_invMassB; + float 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_axialMass = mA + mB + iA * m_a1 * m_a1 + iB * m_a2 * m_a2; + if (m_axialMass > 0.0f) + { + m_axialMass = 1.0f / m_axialMass; + } + } + + // Prismatic constraint. + { + m_perp = b2Mul(qA, m_localYAxisA); + + m_s1 = b2Cross(d + rA, m_perp); + m_s2 = b2Cross(rB, m_perp); + + float k11 = mA + mB + iA * m_s1 * m_s1 + iB * m_s2 * m_s2; + float k12 = iA * m_s1 + iB * m_s2; + float k22 = iA + iB; + if (k22 == 0.0f) + { + // For bodies with fixed rotation. + k22 = 1.0f; + } + + m_K.ex.Set(k11, k12); + m_K.ey.Set(k12, k22); + } + + if (m_enableLimit) + { + m_translation = b2Dot(m_axis, d); + } + else + { + m_lowerImpulse = 0.0f; + m_upperImpulse = 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; + m_lowerImpulse *= data.step.dtRatio; + m_upperImpulse *= data.step.dtRatio; + + float axialImpulse = m_motorImpulse + m_lowerImpulse - m_upperImpulse; + b2Vec2 P = m_impulse.x * m_perp + axialImpulse * m_axis; + float LA = m_impulse.x * m_s1 + m_impulse.y + axialImpulse * m_a1; + float LB = m_impulse.x * m_s2 + m_impulse.y + axialImpulse * m_a2; + + vA -= mA * P; + wA -= iA * LA; + + vB += mB * P; + wB += iB * LB; + } + else + { + m_impulse.SetZero(); + m_motorImpulse = 0.0f; + m_lowerImpulse = 0.0f; + m_upperImpulse = 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; + float wA = data.velocities[m_indexA].w; + b2Vec2 vB = data.velocities[m_indexB].v; + float wB = data.velocities[m_indexB].w; + + float mA = m_invMassA, mB = m_invMassB; + float iA = m_invIA, iB = m_invIB; + + // Solve linear motor constraint + if (m_enableMotor) + { + float Cdot = b2Dot(m_axis, vB - vA) + m_a2 * wB - m_a1 * wA; + float impulse = m_axialMass * (m_motorSpeed - Cdot); + float oldImpulse = m_motorImpulse; + float maxImpulse = data.step.dt * m_maxMotorForce; + m_motorImpulse = b2Clamp(m_motorImpulse + impulse, -maxImpulse, maxImpulse); + impulse = m_motorImpulse - oldImpulse; + + b2Vec2 P = impulse * m_axis; + float LA = impulse * m_a1; + float LB = impulse * m_a2; + + vA -= mA * P; + wA -= iA * LA; + vB += mB * P; + wB += iB * LB; + } + + if (m_enableLimit) + { + // Lower limit + { + float C = m_translation - m_lowerTranslation; + float Cdot = b2Dot(m_axis, vB - vA) + m_a2 * wB - m_a1 * wA; + float impulse = -m_axialMass * (Cdot + b2Max(C, 0.0f) * data.step.inv_dt); + float oldImpulse = m_lowerImpulse; + m_lowerImpulse = b2Max(m_lowerImpulse + impulse, 0.0f); + impulse = m_lowerImpulse - oldImpulse; + + b2Vec2 P = impulse * m_axis; + float LA = impulse * m_a1; + float LB = impulse * m_a2; + + vA -= mA * P; + wA -= iA * LA; + vB += mB * P; + wB += iB * LB; + } + + // Upper limit + // Note: signs are flipped to keep C positive when the constraint is satisfied. + // This also keeps the impulse positive when the limit is active. + { + float C = m_upperTranslation - m_translation; + float Cdot = b2Dot(m_axis, vA - vB) + m_a1 * wA - m_a2 * wB; + float impulse = -m_axialMass * (Cdot + b2Max(C, 0.0f) * data.step.inv_dt); + float oldImpulse = m_upperImpulse; + m_upperImpulse = b2Max(m_upperImpulse + impulse, 0.0f); + impulse = m_upperImpulse - oldImpulse; + + b2Vec2 P = impulse * m_axis; + float LA = impulse * m_a1; + float LB = impulse * m_a2; + + vA += mA * P; + wA += iA * LA; + vB -= mB * P; + wB -= iB * LB; + } + } + + // Solve the prismatic constraint in block form. + { + b2Vec2 Cdot; + Cdot.x = b2Dot(m_perp, vB - vA) + m_s2 * wB - m_s1 * wA; + Cdot.y = wB - wA; + + b2Vec2 df = m_K.Solve(-Cdot); + m_impulse += df; + + b2Vec2 P = df.x * m_perp; + float LA = df.x * m_s1 + df.y; + float 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; + float aA = data.positions[m_indexA].a; + b2Vec2 cB = data.positions[m_indexB].c; + float aB = data.positions[m_indexB].a; + + b2Rot qA(aA), qB(aB); + + float mA = m_invMassA, mB = m_invMassB; + float 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); + float a1 = b2Cross(d + rA, axis); + float a2 = b2Cross(rB, axis); + b2Vec2 perp = b2Mul(qA, m_localYAxisA); + + float s1 = b2Cross(d + rA, perp); + float s2 = b2Cross(rB, perp); + + b2Vec3 impulse; + b2Vec2 C1; + C1.x = b2Dot(perp, d); + C1.y = aB - aA - m_referenceAngle; + + float linearError = b2Abs(C1.x); + float angularError = b2Abs(C1.y); + + bool active = false; + float C2 = 0.0f; + if (m_enableLimit) + { + float translation = b2Dot(axis, d); + if (b2Abs(m_upperTranslation - m_lowerTranslation) < 2.0f * b2_linearSlop) + { + C2 = translation; + linearError = b2Max(linearError, b2Abs(translation)); + active = true; + } + else if (translation <= m_lowerTranslation) + { + C2 = b2Min(translation - m_lowerTranslation, 0.0f); + linearError = b2Max(linearError, m_lowerTranslation - translation); + active = true; + } + else if (translation >= m_upperTranslation) + { + C2 = b2Max(translation - m_upperTranslation, 0.0f); + linearError = b2Max(linearError, translation - m_upperTranslation); + active = true; + } + } + + if (active) + { + float k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2; + float k12 = iA * s1 + iB * s2; + float k13 = iA * s1 * a1 + iB * s2 * a2; + float k22 = iA + iB; + if (k22 == 0.0f) + { + // For fixed rotation + k22 = 1.0f; + } + float k23 = iA * a1 + iB * a2; + float 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 + { + float k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2; + float k12 = iA * s1 + iB * s2; + float 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; + float LA = impulse.x * s1 + impulse.y + impulse.z * a1; + float 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(float inv_dt) const +{ + return inv_dt * (m_impulse.x * m_perp + (m_motorImpulse + m_lowerImpulse + m_upperImpulse) * m_axis); +} + +float b2PrismaticJoint::GetReactionTorque(float inv_dt) const +{ + return inv_dt * m_impulse.y; +} + +float 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); + + float translation = b2Dot(d, axis); + return translation; +} + +float 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; + float wA = bA->m_angularVelocity; + float wB = bB->m_angularVelocity; + + float 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_lowerImpulse = 0.0f; + m_upperImpulse = 0.0f; + } +} + +float b2PrismaticJoint::GetLowerLimit() const +{ + return m_lowerTranslation; +} + +float b2PrismaticJoint::GetUpperLimit() const +{ + return m_upperTranslation; +} + +void b2PrismaticJoint::SetLimits(float lower, float 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_lowerImpulse = 0.0f; + m_upperImpulse = 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(float speed) +{ + if (speed != m_motorSpeed) + { + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_motorSpeed = speed; + } +} + +void b2PrismaticJoint::SetMaxMotorForce(float force) +{ + if (force != m_maxMotorForce) + { + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_maxMotorForce = force; + } +} + +float b2PrismaticJoint::GetMotorForce(float inv_dt) const +{ + return inv_dt * m_motorImpulse; +} + +void b2PrismaticJoint::Dump() +{ + // FLT_DECIMAL_DIG == 9 + + int32 indexA = m_bodyA->m_islandIndex; + int32 indexB = m_bodyB->m_islandIndex; + + b2Dump(" b2PrismaticJointDef jd;\n"); + b2Dump(" jd.bodyA = bodies[%d];\n", indexA); + b2Dump(" jd.bodyB = bodies[%d];\n", indexB); + b2Dump(" jd.collideConnected = bool(%d);\n", m_collideConnected); + b2Dump(" jd.localAnchorA.Set(%.9g, %.9g);\n", m_localAnchorA.x, m_localAnchorA.y); + b2Dump(" jd.localAnchorB.Set(%.9g, %.9g);\n", m_localAnchorB.x, m_localAnchorB.y); + b2Dump(" jd.localAxisA.Set(%.9g, %.9g);\n", m_localXAxisA.x, m_localXAxisA.y); + b2Dump(" jd.referenceAngle = %.9g;\n", m_referenceAngle); + b2Dump(" jd.enableLimit = bool(%d);\n", m_enableLimit); + b2Dump(" jd.lowerTranslation = %.9g;\n", m_lowerTranslation); + b2Dump(" jd.upperTranslation = %.9g;\n", m_upperTranslation); + b2Dump(" jd.enableMotor = bool(%d);\n", m_enableMotor); + b2Dump(" jd.motorSpeed = %.9g;\n", m_motorSpeed); + b2Dump(" jd.maxMotorForce = %.9g;\n", m_maxMotorForce); + b2Dump(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); +} + +/// +void b2PrismaticJoint::Draw(b2Draw* draw) const +{ + const b2Transform& xfA = m_bodyA->GetTransform(); + const b2Transform& xfB = m_bodyB->GetTransform(); + b2Vec2 pA = b2Mul(xfA, m_localAnchorA); + b2Vec2 pB = b2Mul(xfB, m_localAnchorB); + + b2Vec2 axis = b2Mul(xfA.q, m_localXAxisA); + + b2Color c1(0.7f, 0.7f, 0.7f); + b2Color c2(0.3f, 0.9f, 0.3f); + b2Color c3(0.9f, 0.3f, 0.3f); + b2Color c4(0.3f, 0.3f, 0.9f); + b2Color c5(0.4f, 0.4f, 0.4f); + + draw->DrawSegment(pA, pB, c5); + + if (m_enableLimit) + { + b2Vec2 lower = pA + m_lowerTranslation * axis; + b2Vec2 upper = pA + m_upperTranslation * axis; + b2Vec2 perp = b2Mul(xfA.q, m_localYAxisA); + draw->DrawSegment(lower, upper, c1); + draw->DrawSegment(lower - 0.5f * perp, lower + 0.5f * perp, c2); + draw->DrawSegment(upper - 0.5f * perp, upper + 0.5f * perp, c3); + } + else + { + draw->DrawSegment(pA - 1.0f * axis, pA + 1.0f * axis, c1); + } + + draw->DrawPoint(pA, 5.0f, c1); + draw->DrawPoint(pB, 5.0f, c4); +} diff --git a/src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.cpp b/src/libraries/Box2D/Dynamics/b2_pulley_joint.cpp similarity index 62% rename from src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.cpp rename to src/libraries/Box2D/Dynamics/b2_pulley_joint.cpp index 9cd340f1b..099e57e49 100644 --- a/src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.cpp +++ b/src/libraries/Box2D/Dynamics/b2_pulley_joint.cpp @@ -1,24 +1,28 @@ -/* -* 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. -*/ +// MIT License -#include -#include -#include +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_body.h" +#include "box2d/b2_pulley_joint.h" +#include "box2d/b2_time_step.h" // Pulley: // length1 = norm(p1 - s1) @@ -35,7 +39,7 @@ void b2PulleyJointDef::Initialize(b2Body* bA, b2Body* bB, const b2Vec2& groundA, const b2Vec2& groundB, const b2Vec2& anchorA, const b2Vec2& anchorB, - float32 r) + float r) { bodyA = bA; bodyB = bB; @@ -82,14 +86,14 @@ void b2PulleyJoint::InitVelocityConstraints(const b2SolverData& data) m_invIB = m_bodyB->m_invI; b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; + float aA = data.positions[m_indexA].a; b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; + float wA = data.velocities[m_indexA].w; b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; + float aB = data.positions[m_indexB].a; b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; + float wB = data.velocities[m_indexB].w; b2Rot qA(aA), qB(aB); @@ -100,8 +104,8 @@ void b2PulleyJoint::InitVelocityConstraints(const b2SolverData& data) m_uA = cA + m_rA - m_groundAnchorA; m_uB = cB + m_rB - m_groundAnchorB; - float32 lengthA = m_uA.Length(); - float32 lengthB = m_uB.Length(); + float lengthA = m_uA.Length(); + float lengthB = m_uB.Length(); if (lengthA > 10.0f * b2_linearSlop) { @@ -122,11 +126,11 @@ void b2PulleyJoint::InitVelocityConstraints(const b2SolverData& data) } // Compute effective mass. - float32 ruA = b2Cross(m_rA, m_uA); - float32 ruB = b2Cross(m_rB, m_uB); + float ruA = b2Cross(m_rA, m_uA); + float ruB = b2Cross(m_rB, m_uB); - float32 mA = m_invMassA + m_invIA * ruA * ruA; - float32 mB = m_invMassB + m_invIB * ruB * ruB; + float mA = m_invMassA + m_invIA * ruA * ruA; + float mB = m_invMassB + m_invIB * ruB * ruB; m_mass = mA + m_ratio * m_ratio * mB; @@ -163,15 +167,15 @@ void b2PulleyJoint::InitVelocityConstraints(const b2SolverData& data) void b2PulleyJoint::SolveVelocityConstraints(const b2SolverData& data) { b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; + float wA = data.velocities[m_indexA].w; b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; + float 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; + float Cdot = -b2Dot(m_uA, vpA) - m_ratio * b2Dot(m_uB, vpB); + float impulse = -m_mass * Cdot; m_impulse += impulse; b2Vec2 PA = -impulse * m_uA; @@ -190,9 +194,9 @@ void b2PulleyJoint::SolveVelocityConstraints(const b2SolverData& data) bool b2PulleyJoint::SolvePositionConstraints(const b2SolverData& data) { b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; + float aA = data.positions[m_indexA].a; b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; + float aB = data.positions[m_indexB].a; b2Rot qA(aA), qB(aB); @@ -203,8 +207,8 @@ bool b2PulleyJoint::SolvePositionConstraints(const b2SolverData& data) b2Vec2 uA = cA + rA - m_groundAnchorA; b2Vec2 uB = cB + rB - m_groundAnchorB; - float32 lengthA = uA.Length(); - float32 lengthB = uB.Length(); + float lengthA = uA.Length(); + float lengthB = uB.Length(); if (lengthA > 10.0f * b2_linearSlop) { @@ -225,23 +229,23 @@ bool b2PulleyJoint::SolvePositionConstraints(const b2SolverData& data) } // Compute effective mass. - float32 ruA = b2Cross(rA, uA); - float32 ruB = b2Cross(rB, uB); + float ruA = b2Cross(rA, uA); + float ruB = b2Cross(rB, uB); - float32 mA = m_invMassA + m_invIA * ruA * ruA; - float32 mB = m_invMassB + m_invIB * ruB * ruB; + float mA = m_invMassA + m_invIA * ruA * ruA; + float mB = m_invMassB + m_invIB * ruB * ruB; - float32 mass = mA + m_ratio * m_ratio * mB; + float 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); + float C = m_constant - lengthA - m_ratio * lengthB; + float linearError = b2Abs(C); - float32 impulse = -mass * C; + float impulse = -mass * C; b2Vec2 PA = -impulse * uA; b2Vec2 PB = -m_ratio * impulse * uB; @@ -269,13 +273,13 @@ b2Vec2 b2PulleyJoint::GetAnchorB() const return m_bodyB->GetWorldPoint(m_localAnchorB); } -b2Vec2 b2PulleyJoint::GetReactionForce(float32 inv_dt) const +b2Vec2 b2PulleyJoint::GetReactionForce(float inv_dt) const { b2Vec2 P = m_impulse * m_uB; return inv_dt * P; } -float32 b2PulleyJoint::GetReactionTorque(float32 inv_dt) const +float b2PulleyJoint::GetReactionTorque(float inv_dt) const { B2_NOT_USED(inv_dt); return 0.0f; @@ -291,22 +295,22 @@ b2Vec2 b2PulleyJoint::GetGroundAnchorB() const return m_groundAnchorB; } -float32 b2PulleyJoint::GetLengthA() const +float b2PulleyJoint::GetLengthA() const { return m_lengthA; } -float32 b2PulleyJoint::GetLengthB() const +float b2PulleyJoint::GetLengthB() const { return m_lengthB; } -float32 b2PulleyJoint::GetRatio() const +float b2PulleyJoint::GetRatio() const { return m_ratio; } -float32 b2PulleyJoint::GetCurrentLengthA() const +float b2PulleyJoint::GetCurrentLengthA() const { b2Vec2 p = m_bodyA->GetWorldPoint(m_localAnchorA); b2Vec2 s = m_groundAnchorA; @@ -314,7 +318,7 @@ float32 b2PulleyJoint::GetCurrentLengthA() const return d.Length(); } -float32 b2PulleyJoint::GetCurrentLengthB() const +float b2PulleyJoint::GetCurrentLengthB() const { b2Vec2 p = m_bodyB->GetWorldPoint(m_localAnchorB); b2Vec2 s = m_groundAnchorB; @@ -327,18 +331,18 @@ 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); + b2Dump(" b2PulleyJointDef jd;\n"); + b2Dump(" jd.bodyA = bodies[%d];\n", indexA); + b2Dump(" jd.bodyB = bodies[%d];\n", indexB); + b2Dump(" jd.collideConnected = bool(%d);\n", m_collideConnected); + b2Dump(" jd.groundAnchorA.Set(%.9g, %.9g);\n", m_groundAnchorA.x, m_groundAnchorA.y); + b2Dump(" jd.groundAnchorB.Set(%.9g, %.9g);\n", m_groundAnchorB.x, m_groundAnchorB.y); + b2Dump(" jd.localAnchorA.Set(%.9g, %.9g);\n", m_localAnchorA.x, m_localAnchorA.y); + b2Dump(" jd.localAnchorB.Set(%.9g, %.9g);\n", m_localAnchorB.x, m_localAnchorB.y); + b2Dump(" jd.lengthA = %.9g;\n", m_lengthA); + b2Dump(" jd.lengthB = %.9g;\n", m_lengthB); + b2Dump(" jd.ratio = %.9g;\n", m_ratio); + b2Dump(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); } void b2PulleyJoint::ShiftOrigin(const b2Vec2& newOrigin) diff --git a/src/libraries/Box2D/Dynamics/b2_revolute_joint.cpp b/src/libraries/Box2D/Dynamics/b2_revolute_joint.cpp new file mode 100644 index 000000000..35162b084 --- /dev/null +++ b/src/libraries/Box2D/Dynamics/b2_revolute_joint.cpp @@ -0,0 +1,501 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_body.h" +#include "box2d/b2_draw.h" +#include "box2d/b2_revolute_joint.h" +#include "box2d/b2_time_step.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_axialMass = 0.0f; + m_motorImpulse = 0.0f; + m_lowerImpulse = 0.0f; + m_upperImpulse = 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_angle = 0.0f; +} + +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; + + float aA = data.positions[m_indexA].a; + b2Vec2 vA = data.velocities[m_indexA].v; + float wA = data.velocities[m_indexA].w; + + float aB = data.positions[m_indexB].a; + b2Vec2 vB = data.velocities[m_indexB].v; + float 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] + // r_skew = [-ry; rx] + + // Matlab + // K = [ mA+r1y^2*iA+mB+r2y^2*iB, -r1y*iA*r1x-r2y*iB*r2x] + // [ -r1y*iA*r1x-r2y*iB*r2x, mA+r1x^2*iA+mB+r2x^2*iB] + + float mA = m_invMassA, mB = m_invMassB; + float iA = m_invIA, iB = m_invIB; + + m_K.ex.x = mA + mB + m_rA.y * m_rA.y * iA + m_rB.y * m_rB.y * iB; + m_K.ey.x = -m_rA.y * m_rA.x * iA - m_rB.y * m_rB.x * iB; + m_K.ex.y = m_K.ey.x; + m_K.ey.y = mA + mB + m_rA.x * m_rA.x * iA + m_rB.x * m_rB.x * iB; + + m_axialMass = iA + iB; + bool fixedRotation; + if (m_axialMass > 0.0f) + { + m_axialMass = 1.0f / m_axialMass; + fixedRotation = false; + } + else + { + fixedRotation = true; + } + + m_angle = aB - aA - m_referenceAngle; + if (m_enableLimit == false || fixedRotation) + { + m_lowerImpulse = 0.0f; + m_upperImpulse = 0.0f; + } + + if (m_enableMotor == false || fixedRotation) + { + m_motorImpulse = 0.0f; + } + + if (data.step.warmStarting) + { + // Scale impulses to support a variable time step. + m_impulse *= data.step.dtRatio; + m_motorImpulse *= data.step.dtRatio; + m_lowerImpulse *= data.step.dtRatio; + m_upperImpulse *= data.step.dtRatio; + + float axialImpulse = m_motorImpulse + m_lowerImpulse - m_upperImpulse; + b2Vec2 P(m_impulse.x, m_impulse.y); + + vA -= mA * P; + wA -= iA * (b2Cross(m_rA, P) + axialImpulse); + + vB += mB * P; + wB += iB * (b2Cross(m_rB, P) + axialImpulse); + } + else + { + m_impulse.SetZero(); + m_motorImpulse = 0.0f; + m_lowerImpulse = 0.0f; + m_upperImpulse = 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; + float wA = data.velocities[m_indexA].w; + b2Vec2 vB = data.velocities[m_indexB].v; + float wB = data.velocities[m_indexB].w; + + float mA = m_invMassA, mB = m_invMassB; + float iA = m_invIA, iB = m_invIB; + + bool fixedRotation = (iA + iB == 0.0f); + + // Solve motor constraint. + if (m_enableMotor && fixedRotation == false) + { + float Cdot = wB - wA - m_motorSpeed; + float impulse = -m_axialMass * Cdot; + float oldImpulse = m_motorImpulse; + float maxImpulse = data.step.dt * m_maxMotorTorque; + m_motorImpulse = b2Clamp(m_motorImpulse + impulse, -maxImpulse, maxImpulse); + impulse = m_motorImpulse - oldImpulse; + + wA -= iA * impulse; + wB += iB * impulse; + } + + if (m_enableLimit && fixedRotation == false) + { + // Lower limit + { + float C = m_angle - m_lowerAngle; + float Cdot = wB - wA; + float impulse = -m_axialMass * (Cdot + b2Max(C, 0.0f) * data.step.inv_dt); + float oldImpulse = m_lowerImpulse; + m_lowerImpulse = b2Max(m_lowerImpulse + impulse, 0.0f); + impulse = m_lowerImpulse - oldImpulse; + + wA -= iA * impulse; + wB += iB * impulse; + } + + // Upper limit + // Note: signs are flipped to keep C positive when the constraint is satisfied. + // This also keeps the impulse positive when the limit is active. + { + float C = m_upperAngle - m_angle; + float Cdot = wA - wB; + float impulse = -m_axialMass * (Cdot + b2Max(C, 0.0f) * data.step.inv_dt); + float oldImpulse = m_upperImpulse; + m_upperImpulse = b2Max(m_upperImpulse + impulse, 0.0f); + impulse = m_upperImpulse - oldImpulse; + + wA += iA * impulse; + wB -= iB * impulse; + } + } + + // Solve point-to-point constraint + { + b2Vec2 Cdot = vB + b2Cross(wB, m_rB) - vA - b2Cross(wA, m_rA); + b2Vec2 impulse = m_K.Solve(-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; + float aA = data.positions[m_indexA].a; + b2Vec2 cB = data.positions[m_indexB].c; + float aB = data.positions[m_indexB].a; + + b2Rot qA(aA), qB(aB); + + float angularError = 0.0f; + float positionError = 0.0f; + + bool fixedRotation = (m_invIA + m_invIB == 0.0f); + + // Solve angular limit constraint + if (m_enableLimit && fixedRotation == false) + { + float angle = aB - aA - m_referenceAngle; + float C = 0.0f; + + if (b2Abs(m_upperAngle - m_lowerAngle) < 2.0f * b2_angularSlop) + { + // Prevent large angular corrections + C = b2Clamp(angle - m_lowerAngle, -b2_maxAngularCorrection, b2_maxAngularCorrection); + } + else if (angle <= m_lowerAngle) + { + // Prevent large angular corrections and allow some slop. + C = b2Clamp(angle - m_lowerAngle + b2_angularSlop, -b2_maxAngularCorrection, 0.0f); + } + else if (angle >= m_upperAngle) + { + // Prevent large angular corrections and allow some slop. + C = b2Clamp(angle - m_upperAngle - b2_angularSlop, 0.0f, b2_maxAngularCorrection); + } + + float limitImpulse = -m_axialMass * C; + aA -= m_invIA * limitImpulse; + aB += m_invIB * limitImpulse; + angularError = b2Abs(C); + } + + // 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(); + + float mA = m_invMassA, mB = m_invMassB; + float 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(float inv_dt) const +{ + b2Vec2 P(m_impulse.x, m_impulse.y); + return inv_dt * P; +} + +float b2RevoluteJoint::GetReactionTorque(float inv_dt) const +{ + return inv_dt * (m_lowerImpulse + m_upperImpulse); +} + +float b2RevoluteJoint::GetJointAngle() const +{ + b2Body* bA = m_bodyA; + b2Body* bB = m_bodyB; + return bB->m_sweep.a - bA->m_sweep.a - m_referenceAngle; +} + +float 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; + } +} + +float b2RevoluteJoint::GetMotorTorque(float inv_dt) const +{ + return inv_dt * m_motorImpulse; +} + +void b2RevoluteJoint::SetMotorSpeed(float speed) +{ + if (speed != m_motorSpeed) + { + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_motorSpeed = speed; + } +} + +void b2RevoluteJoint::SetMaxMotorTorque(float 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_lowerImpulse = 0.0f; + m_upperImpulse = 0.0f; + } +} + +float b2RevoluteJoint::GetLowerLimit() const +{ + return m_lowerAngle; +} + +float b2RevoluteJoint::GetUpperLimit() const +{ + return m_upperAngle; +} + +void b2RevoluteJoint::SetLimits(float lower, float upper) +{ + b2Assert(lower <= upper); + + if (lower != m_lowerAngle || upper != m_upperAngle) + { + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_lowerImpulse = 0.0f; + m_upperImpulse = 0.0f; + m_lowerAngle = lower; + m_upperAngle = upper; + } +} + +void b2RevoluteJoint::Dump() +{ + int32 indexA = m_bodyA->m_islandIndex; + int32 indexB = m_bodyB->m_islandIndex; + + b2Dump(" b2RevoluteJointDef jd;\n"); + b2Dump(" jd.bodyA = bodies[%d];\n", indexA); + b2Dump(" jd.bodyB = bodies[%d];\n", indexB); + b2Dump(" jd.collideConnected = bool(%d);\n", m_collideConnected); + b2Dump(" jd.localAnchorA.Set(%.9g, %.9g);\n", m_localAnchorA.x, m_localAnchorA.y); + b2Dump(" jd.localAnchorB.Set(%.9g, %.9g);\n", m_localAnchorB.x, m_localAnchorB.y); + b2Dump(" jd.referenceAngle = %.9g;\n", m_referenceAngle); + b2Dump(" jd.enableLimit = bool(%d);\n", m_enableLimit); + b2Dump(" jd.lowerAngle = %.9g;\n", m_lowerAngle); + b2Dump(" jd.upperAngle = %.9g;\n", m_upperAngle); + b2Dump(" jd.enableMotor = bool(%d);\n", m_enableMotor); + b2Dump(" jd.motorSpeed = %.9g;\n", m_motorSpeed); + b2Dump(" jd.maxMotorTorque = %.9g;\n", m_maxMotorTorque); + b2Dump(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); +} + +/// +void b2RevoluteJoint::Draw(b2Draw* draw) const +{ + const b2Transform& xfA = m_bodyA->GetTransform(); + const b2Transform& xfB = m_bodyB->GetTransform(); + b2Vec2 pA = b2Mul(xfA, m_localAnchorA); + b2Vec2 pB = b2Mul(xfB, m_localAnchorB); + + b2Color c1(0.7f, 0.7f, 0.7f); + b2Color c2(0.3f, 0.9f, 0.3f); + b2Color c3(0.9f, 0.3f, 0.3f); + b2Color c4(0.3f, 0.3f, 0.9f); + b2Color c5(0.4f, 0.4f, 0.4f); + + draw->DrawPoint(pA, 5.0f, c4); + draw->DrawPoint(pB, 5.0f, c5); + + float aA = m_bodyA->GetAngle(); + float aB = m_bodyB->GetAngle(); + float angle = aB - aA - m_referenceAngle; + + const float L = 0.5f; + + b2Vec2 r = L * b2Vec2(cosf(angle), sinf(angle)); + draw->DrawSegment(pB, pB + r, c1); + draw->DrawCircle(pB, L, c1); + + if (m_enableLimit) + { + b2Vec2 rlo = L * b2Vec2(cosf(m_lowerAngle), sinf(m_lowerAngle)); + b2Vec2 rhi = L * b2Vec2(cosf(m_upperAngle), sinf(m_upperAngle)); + + draw->DrawSegment(pB, pB + rlo, c2); + draw->DrawSegment(pB, pB + rhi, c3); + } + + b2Color color(0.5f, 0.8f, 0.8f); + draw->DrawSegment(xfA.p, pA, color); + draw->DrawSegment(pA, pB, color); + draw->DrawSegment(xfB.p, pB, color); +} diff --git a/src/libraries/Box2D/Dynamics/Joints/b2RopeJoint.cpp b/src/libraries/Box2D/Dynamics/b2_rope_joint.cpp similarity index 57% rename from src/libraries/Box2D/Dynamics/Joints/b2RopeJoint.cpp rename to src/libraries/Box2D/Dynamics/b2_rope_joint.cpp index 952ee7a3e..ebe800f82 100644 --- a/src/libraries/Box2D/Dynamics/Joints/b2RopeJoint.cpp +++ b/src/libraries/Box2D/Dynamics/b2_rope_joint.cpp @@ -1,24 +1,28 @@ -/* -* 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. -*/ +// MIT License -#include -#include -#include +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_body.h" +#include "box2d/b2_rope_joint.h" +#include "box2d/b2_time_step.h" // Limit: @@ -39,7 +43,6 @@ b2RopeJoint::b2RopeJoint(const b2RopeJointDef* def) m_mass = 0.0f; m_impulse = 0.0f; - m_state = e_inactiveLimit; m_length = 0.0f; } @@ -55,14 +58,14 @@ void b2RopeJoint::InitVelocityConstraints(const b2SolverData& data) m_invIB = m_bodyB->m_invI; b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; + float aA = data.positions[m_indexA].a; b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; + float wA = data.velocities[m_indexA].w; b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; + float aB = data.positions[m_indexB].a; b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; + float wB = data.velocities[m_indexB].w; b2Rot qA(aA), qB(aB); @@ -72,16 +75,6 @@ void b2RopeJoint::InitVelocityConstraints(const b2SolverData& data) 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; @@ -95,9 +88,9 @@ void b2RopeJoint::InitVelocityConstraints(const b2SolverData& data) } // 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; + float crA = b2Cross(m_rA, m_u); + float crB = b2Cross(m_rB, m_u); + float invMass = m_invMassA + m_invIA * crA * crA + m_invMassB + m_invIB * crB * crB; m_mass = invMass != 0.0f ? 1.0f / invMass : 0.0f; @@ -126,15 +119,15 @@ void b2RopeJoint::InitVelocityConstraints(const b2SolverData& data) void b2RopeJoint::SolveVelocityConstraints(const b2SolverData& data) { b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; + float wA = data.velocities[m_indexA].w; b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; + float 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); + float C = m_length - m_maxLength; + float Cdot = b2Dot(m_u, vpB - vpA); // Predictive constraint. if (C < 0.0f) @@ -142,8 +135,8 @@ void b2RopeJoint::SolveVelocityConstraints(const b2SolverData& data) Cdot += data.step.inv_dt * C; } - float32 impulse = -m_mass * Cdot; - float32 oldImpulse = m_impulse; + float impulse = -m_mass * Cdot; + float oldImpulse = m_impulse; m_impulse = b2Min(0.0f, m_impulse + impulse); impulse = m_impulse - oldImpulse; @@ -162,9 +155,9 @@ void b2RopeJoint::SolveVelocityConstraints(const b2SolverData& data) bool b2RopeJoint::SolvePositionConstraints(const b2SolverData& data) { b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; + float aA = data.positions[m_indexA].a; b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; + float aB = data.positions[m_indexB].a; b2Rot qA(aA), qB(aB); @@ -172,12 +165,12 @@ bool b2RopeJoint::SolvePositionConstraints(const b2SolverData& data) b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); b2Vec2 u = cB + rB - cA - rA; - float32 length = u.Normalize(); - float32 C = length - m_maxLength; + m_length = u.Normalize(); + float C = m_length - m_maxLength; C = b2Clamp(C, 0.0f, b2_maxLinearCorrection); - float32 impulse = -m_mass * C; + float impulse = -m_mass * C; b2Vec2 P = impulse * u; cA -= m_invMassA * P; @@ -190,7 +183,7 @@ bool b2RopeJoint::SolvePositionConstraints(const b2SolverData& data) data.positions[m_indexB].c = cB; data.positions[m_indexB].a = aB; - return length - m_maxLength < b2_linearSlop; + return m_length - m_maxLength < b2_linearSlop; } b2Vec2 b2RopeJoint::GetAnchorA() const @@ -203,26 +196,26 @@ b2Vec2 b2RopeJoint::GetAnchorB() const return m_bodyB->GetWorldPoint(m_localAnchorB); } -b2Vec2 b2RopeJoint::GetReactionForce(float32 inv_dt) const +b2Vec2 b2RopeJoint::GetReactionForce(float inv_dt) const { b2Vec2 F = (inv_dt * m_impulse) * m_u; return F; } -float32 b2RopeJoint::GetReactionTorque(float32 inv_dt) const +float b2RopeJoint::GetReactionTorque(float inv_dt) const { B2_NOT_USED(inv_dt); return 0.0f; } -float32 b2RopeJoint::GetMaxLength() const +float b2RopeJoint::GetMaxLength() const { return m_maxLength; } -b2LimitState b2RopeJoint::GetLimitState() const +float b2RopeJoint::GetLength() const { - return m_state; + return m_length; } void b2RopeJoint::Dump() @@ -230,12 +223,12 @@ 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); + b2Dump(" b2RopeJointDef jd;\n"); + b2Dump(" jd.bodyA = bodies[%d];\n", indexA); + b2Dump(" jd.bodyB = bodies[%d];\n", indexB); + b2Dump(" jd.collideConnected = bool(%d);\n", m_collideConnected); + b2Dump(" jd.localAnchorA.Set(%.9g, %.9g);\n", m_localAnchorA.x, m_localAnchorA.y); + b2Dump(" jd.localAnchorB.Set(%.9g, %.9g);\n", m_localAnchorB.x, m_localAnchorB.y); + b2Dump(" jd.maxLength = %.9g;\n", m_maxLength); + b2Dump(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); } diff --git a/src/libraries/Box2D/Dynamics/Joints/b2WeldJoint.cpp b/src/libraries/Box2D/Dynamics/b2_weld_joint.cpp similarity index 66% rename from src/libraries/Box2D/Dynamics/Joints/b2WeldJoint.cpp rename to src/libraries/Box2D/Dynamics/b2_weld_joint.cpp index ffdd386b1..df3ee0a3e 100644 --- a/src/libraries/Box2D/Dynamics/Joints/b2WeldJoint.cpp +++ b/src/libraries/Box2D/Dynamics/b2_weld_joint.cpp @@ -1,24 +1,28 @@ -/* -* 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. -*/ +// MIT License -#include -#include -#include +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_body.h" +#include "box2d/b2_time_step.h" +#include "box2d/b2_weld_joint.h" // Point-to-point constraint // C = p2 - p1 @@ -49,8 +53,8 @@ b2WeldJoint::b2WeldJoint(const b2WeldJointDef* def) m_localAnchorA = def->localAnchorA; m_localAnchorB = def->localAnchorB; m_referenceAngle = def->referenceAngle; - m_frequencyHz = def->frequencyHz; - m_dampingRatio = def->dampingRatio; + m_stiffness = def->stiffness; + m_damping = def->damping; m_impulse.SetZero(); } @@ -66,13 +70,13 @@ void b2WeldJoint::InitVelocityConstraints(const b2SolverData& data) m_invIA = m_bodyA->m_invI; m_invIB = m_bodyB->m_invI; - float32 aA = data.positions[m_indexA].a; + float aA = data.positions[m_indexA].a; b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; + float wA = data.velocities[m_indexA].w; - float32 aB = data.positions[m_indexB].a; + float aB = data.positions[m_indexB].a; b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; + float wB = data.velocities[m_indexB].w; b2Rot qA(aA), qB(aB); @@ -88,8 +92,8 @@ void b2WeldJoint::InitVelocityConstraints(const b2SolverData& data) // [ -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; + float mA = m_invMassA, mB = m_invMassB; + float 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; @@ -102,26 +106,22 @@ void b2WeldJoint::InitVelocityConstraints(const b2SolverData& data) K.ey.z = K.ez.y; K.ez.z = iA + iB; - if (m_frequencyHz > 0.0f) + if (m_stiffness > 0.0f) { K.GetInverse22(&m_mass); - float32 invM = iA + iB; - float32 m = invM > 0.0f ? 1.0f / invM : 0.0f; + float invM = iA + iB; - float32 C = aB - aA - m_referenceAngle; - - // Frequency - float32 omega = 2.0f * b2_pi * m_frequencyHz; + float C = aB - aA - m_referenceAngle; // Damping coefficient - float32 d = 2.0f * m * m_dampingRatio * omega; + float d = m_damping; // Spring stiffness - float32 k = m * omega * omega; + float k = m_stiffness; // magic formulas - float32 h = data.step.dt; + float 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; @@ -169,18 +169,18 @@ void b2WeldJoint::InitVelocityConstraints(const b2SolverData& data) void b2WeldJoint::SolveVelocityConstraints(const b2SolverData& data) { b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; + float wA = data.velocities[m_indexA].w; b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; + float wB = data.velocities[m_indexB].w; - float32 mA = m_invMassA, mB = m_invMassB; - float32 iA = m_invIA, iB = m_invIB; + float mA = m_invMassA, mB = m_invMassB; + float iA = m_invIA, iB = m_invIB; - if (m_frequencyHz > 0.0f) + if (m_stiffness > 0.0f) { - float32 Cdot2 = wB - wA; + float Cdot2 = wB - wA; - float32 impulse2 = -m_mass.ez.z * (Cdot2 + m_bias + m_gamma * m_impulse.z); + float impulse2 = -m_mass.ez.z * (Cdot2 + m_bias + m_gamma * m_impulse.z); m_impulse.z += impulse2; wA -= iA * impulse2; @@ -203,7 +203,7 @@ void b2WeldJoint::SolveVelocityConstraints(const b2SolverData& data) else { b2Vec2 Cdot1 = vB + b2Cross(wB, m_rB) - vA - b2Cross(wA, m_rA); - float32 Cdot2 = wB - wA; + float Cdot2 = wB - wA; b2Vec3 Cdot(Cdot1.x, Cdot1.y, Cdot2); b2Vec3 impulse = -b2Mul(m_mass, Cdot); @@ -227,19 +227,19 @@ void b2WeldJoint::SolveVelocityConstraints(const b2SolverData& data) bool b2WeldJoint::SolvePositionConstraints(const b2SolverData& data) { b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; + float aA = data.positions[m_indexA].a; b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; + float 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; + float mA = m_invMassA, mB = m_invMassB; + float 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; + float positionError, angularError; b2Mat33 K; K.ex.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB; @@ -252,7 +252,7 @@ bool b2WeldJoint::SolvePositionConstraints(const b2SolverData& data) K.ey.z = K.ez.y; K.ez.z = iA + iB; - if (m_frequencyHz > 0.0f) + if (m_stiffness > 0.0f) { b2Vec2 C1 = cB + rB - cA - rA; @@ -270,7 +270,7 @@ bool b2WeldJoint::SolvePositionConstraints(const b2SolverData& data) else { b2Vec2 C1 = cB + rB - cA - rA; - float32 C2 = aB - aA - m_referenceAngle; + float C2 = aB - aA - m_referenceAngle; positionError = C1.Length(); angularError = b2Abs(C2); @@ -315,13 +315,13 @@ b2Vec2 b2WeldJoint::GetAnchorB() const return m_bodyB->GetWorldPoint(m_localAnchorB); } -b2Vec2 b2WeldJoint::GetReactionForce(float32 inv_dt) const +b2Vec2 b2WeldJoint::GetReactionForce(float inv_dt) const { b2Vec2 P(m_impulse.x, m_impulse.y); return inv_dt * P; } -float32 b2WeldJoint::GetReactionTorque(float32 inv_dt) const +float b2WeldJoint::GetReactionTorque(float inv_dt) const { return inv_dt * m_impulse.z; } @@ -331,14 +331,14 @@ 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); + b2Dump(" b2WeldJointDef jd;\n"); + b2Dump(" jd.bodyA = bodies[%d];\n", indexA); + b2Dump(" jd.bodyB = bodies[%d];\n", indexB); + b2Dump(" jd.collideConnected = bool(%d);\n", m_collideConnected); + b2Dump(" jd.localAnchorA.Set(%.9g, %.9g);\n", m_localAnchorA.x, m_localAnchorA.y); + b2Dump(" jd.localAnchorB.Set(%.9g, %.9g);\n", m_localAnchorB.x, m_localAnchorB.y); + b2Dump(" jd.referenceAngle = %.9g;\n", m_referenceAngle); + b2Dump(" jd.stiffness = %.9g;\n", m_stiffness); + b2Dump(" jd.damping = %.9g;\n", m_damping); + b2Dump(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); } diff --git a/src/libraries/Box2D/Dynamics/b2_wheel_joint.cpp b/src/libraries/Box2D/Dynamics/b2_wheel_joint.cpp new file mode 100644 index 000000000..3e76678bf --- /dev/null +++ b/src/libraries/Box2D/Dynamics/b2_wheel_joint.cpp @@ -0,0 +1,672 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_body.h" +#include "box2d/b2_draw.h" +#include "box2d/b2_wheel_joint.h" +#include "box2d/b2_time_step.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_axialMass = 0.0f; + m_lowerImpulse = 0.0f; + m_upperImpulse = 0.0f; + m_lowerTranslation = def->lowerTranslation; + m_upperTranslation = def->upperTranslation; + m_enableLimit = def->enableLimit; + + m_maxMotorTorque = def->maxMotorTorque; + m_motorSpeed = def->motorSpeed; + m_enableMotor = def->enableMotor; + + m_bias = 0.0f; + m_gamma = 0.0f; + + m_ax.SetZero(); + m_ay.SetZero(); + + m_stiffness = def->stiffness; + m_damping = def->damping; +} + +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; + + float mA = m_invMassA, mB = m_invMassB; + float iA = m_invIA, iB = m_invIB; + + b2Vec2 cA = data.positions[m_indexA].c; + float aA = data.positions[m_indexA].a; + b2Vec2 vA = data.velocities[m_indexA].v; + float wA = data.velocities[m_indexA].w; + + b2Vec2 cB = data.positions[m_indexB].c; + float aB = data.positions[m_indexB].a; + b2Vec2 vB = data.velocities[m_indexB].v; + float 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_ax = b2Mul(qA, m_localXAxisA); + m_sAx = b2Cross(d + rA, m_ax); + m_sBx = b2Cross(rB, m_ax); + + const float invMass = mA + mB + iA * m_sAx * m_sAx + iB * m_sBx * m_sBx; + if (invMass > 0.0f) + { + m_axialMass = 1.0f / invMass; + } + else + { + m_axialMass = 0.0f; + } + + m_springMass = 0.0f; + m_bias = 0.0f; + m_gamma = 0.0f; + + if (m_stiffness > 0.0f && invMass > 0.0f) + { + m_springMass = 1.0f / invMass; + + float C = b2Dot(d, m_ax); + + // magic formulas + float h = data.step.dt; + m_gamma = h * (m_damping + h * m_stiffness); + if (m_gamma > 0.0f) + { + m_gamma = 1.0f / m_gamma; + } + + m_bias = C * h * m_stiffness * m_gamma; + + m_springMass = invMass + m_gamma; + if (m_springMass > 0.0f) + { + m_springMass = 1.0f / m_springMass; + } + } + else + { + m_springImpulse = 0.0f; + } + + if (m_enableLimit) + { + m_translation = b2Dot(m_ax, d); + } + else + { + m_lowerImpulse = 0.0f; + m_upperImpulse = 0.0f; + } + + 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; + + float axialImpulse = m_springImpulse + m_lowerImpulse - m_upperImpulse; + b2Vec2 P = m_impulse * m_ay + axialImpulse * m_ax; + float LA = m_impulse * m_sAy + axialImpulse * m_sAx + m_motorImpulse; + float LB = m_impulse * m_sBy + axialImpulse * 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; + m_lowerImpulse = 0.0f; + m_upperImpulse = 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) +{ + float mA = m_invMassA, mB = m_invMassB; + float iA = m_invIA, iB = m_invIB; + + b2Vec2 vA = data.velocities[m_indexA].v; + float wA = data.velocities[m_indexA].w; + b2Vec2 vB = data.velocities[m_indexB].v; + float wB = data.velocities[m_indexB].w; + + // Solve spring constraint + { + float Cdot = b2Dot(m_ax, vB - vA) + m_sBx * wB - m_sAx * wA; + float impulse = -m_springMass * (Cdot + m_bias + m_gamma * m_springImpulse); + m_springImpulse += impulse; + + b2Vec2 P = impulse * m_ax; + float LA = impulse * m_sAx; + float LB = impulse * m_sBx; + + vA -= mA * P; + wA -= iA * LA; + + vB += mB * P; + wB += iB * LB; + } + + // Solve rotational motor constraint + { + float Cdot = wB - wA - m_motorSpeed; + float impulse = -m_motorMass * Cdot; + + float oldImpulse = m_motorImpulse; + float maxImpulse = data.step.dt * m_maxMotorTorque; + m_motorImpulse = b2Clamp(m_motorImpulse + impulse, -maxImpulse, maxImpulse); + impulse = m_motorImpulse - oldImpulse; + + wA -= iA * impulse; + wB += iB * impulse; + } + + if (m_enableLimit) + { + // Lower limit + { + float C = m_translation - m_lowerTranslation; + float Cdot = b2Dot(m_ax, vB - vA) + m_sBx * wB - m_sAx * wA; + float impulse = -m_axialMass * (Cdot + b2Max(C, 0.0f) * data.step.inv_dt); + float oldImpulse = m_lowerImpulse; + m_lowerImpulse = b2Max(m_lowerImpulse + impulse, 0.0f); + impulse = m_lowerImpulse - oldImpulse; + + b2Vec2 P = impulse * m_ax; + float LA = impulse * m_sAx; + float LB = impulse * m_sBx; + + vA -= mA * P; + wA -= iA * LA; + vB += mB * P; + wB += iB * LB; + } + + // Upper limit + // Note: signs are flipped to keep C positive when the constraint is satisfied. + // This also keeps the impulse positive when the limit is active. + { + float C = m_upperTranslation - m_translation; + float Cdot = b2Dot(m_ax, vA - vB) + m_sAx * wA - m_sBx * wB; + float impulse = -m_axialMass * (Cdot + b2Max(C, 0.0f) * data.step.inv_dt); + float oldImpulse = m_upperImpulse; + m_upperImpulse = b2Max(m_upperImpulse + impulse, 0.0f); + impulse = m_upperImpulse - oldImpulse; + + b2Vec2 P = impulse * m_ax; + float LA = impulse * m_sAx; + float LB = impulse * m_sBx; + + vA += mA * P; + wA += iA * LA; + vB -= mB * P; + wB -= iB * LB; + } + } + + // Solve point to line constraint + { + float Cdot = b2Dot(m_ay, vB - vA) + m_sBy * wB - m_sAy * wA; + float impulse = -m_mass * Cdot; + m_impulse += impulse; + + b2Vec2 P = impulse * m_ay; + float LA = impulse * m_sAy; + float 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; + float aA = data.positions[m_indexA].a; + b2Vec2 cB = data.positions[m_indexB].c; + float aB = data.positions[m_indexB].a; + + float linearError = 0.0f; + + if (m_enableLimit) + { + 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 ax = b2Mul(qA, m_localXAxisA); + float sAx = b2Cross(d + rA, m_ax); + float sBx = b2Cross(rB, m_ax); + + float C = 0.0f; + float translation = b2Dot(ax, d); + if (b2Abs(m_upperTranslation - m_lowerTranslation) < 2.0f * b2_linearSlop) + { + C = translation; + } + else if (translation <= m_lowerTranslation) + { + C = b2Min(translation - m_lowerTranslation, 0.0f); + } + else if (translation >= m_upperTranslation) + { + C = b2Max(translation - m_upperTranslation, 0.0f); + } + + if (C != 0.0f) + { + + float invMass = m_invMassA + m_invMassB + m_invIA * sAx * sAx + m_invIB * sBx * sBx; + float impulse = 0.0f; + if (invMass != 0.0f) + { + impulse = -C / invMass; + } + + b2Vec2 P = impulse * ax; + float LA = impulse * sAx; + float LB = impulse * sBx; + + cA -= m_invMassA * P; + aA -= m_invIA * LA; + cB += m_invMassB * P; + aB += m_invIB * LB; + + linearError = b2Abs(C); + } + } + + // Solve perpendicular constraint + { + 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); + + float sAy = b2Cross(d + rA, ay); + float sBy = b2Cross(rB, ay); + + float C = b2Dot(d, ay); + + float invMass = m_invMassA + m_invMassB + m_invIA * m_sAy * m_sAy + m_invIB * m_sBy * m_sBy; + + float impulse = 0.0f; + if (invMass != 0.0f) + { + impulse = - C / invMass; + } + + b2Vec2 P = impulse * ay; + float LA = impulse * sAy; + float LB = impulse * sBy; + + cA -= m_invMassA * P; + aA -= m_invIA * LA; + cB += m_invMassB * P; + aB += m_invIB * LB; + + linearError = b2Max(linearError, b2Abs(C)); + } + + 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 b2WheelJoint::GetAnchorA() const +{ + return m_bodyA->GetWorldPoint(m_localAnchorA); +} + +b2Vec2 b2WheelJoint::GetAnchorB() const +{ + return m_bodyB->GetWorldPoint(m_localAnchorB); +} + +b2Vec2 b2WheelJoint::GetReactionForce(float inv_dt) const +{ + return inv_dt * (m_impulse * m_ay + m_springImpulse * m_ax); +} + +float b2WheelJoint::GetReactionTorque(float inv_dt) const +{ + return inv_dt * m_motorImpulse; +} + +float 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); + + float translation = b2Dot(d, axis); + return translation; +} + +float 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; + float wA = bA->m_angularVelocity; + float wB = bB->m_angularVelocity; + + float speed = b2Dot(d, b2Cross(wA, axis)) + b2Dot(axis, vB + b2Cross(wB, rB) - vA - b2Cross(wA, rA)); + return speed; +} + +float b2WheelJoint::GetJointAngle() const +{ + b2Body* bA = m_bodyA; + b2Body* bB = m_bodyB; + return bB->m_sweep.a - bA->m_sweep.a; +} + +float b2WheelJoint::GetJointAngularSpeed() const +{ + float wA = m_bodyA->m_angularVelocity; + float wB = m_bodyB->m_angularVelocity; + return wB - wA; +} + +bool b2WheelJoint::IsLimitEnabled() const +{ + return m_enableLimit; +} + +void b2WheelJoint::EnableLimit(bool flag) +{ + if (flag != m_enableLimit) + { + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_enableLimit = flag; + m_lowerImpulse = 0.0f; + m_upperImpulse = 0.0f; + } +} + +float b2WheelJoint::GetLowerLimit() const +{ + return m_lowerTranslation; +} + +float b2WheelJoint::GetUpperLimit() const +{ + return m_upperTranslation; +} + +void b2WheelJoint::SetLimits(float lower, float 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_lowerImpulse = 0.0f; + m_upperImpulse = 0.0f; + } +} + +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(float speed) +{ + if (speed != m_motorSpeed) + { + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_motorSpeed = speed; + } +} + +void b2WheelJoint::SetMaxMotorTorque(float torque) +{ + if (torque != m_maxMotorTorque) + { + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_maxMotorTorque = torque; + } +} + +float b2WheelJoint::GetMotorTorque(float inv_dt) const +{ + return inv_dt * m_motorImpulse; +} + +void b2WheelJoint::SetStiffness(float stiffness) +{ + m_stiffness = stiffness; +} + +float b2WheelJoint::GetStiffness() const +{ + return m_stiffness; +} + +void b2WheelJoint::SetDamping(float damping) +{ + m_damping = damping; +} + +float b2WheelJoint::GetDamping() const +{ + return m_damping; +} + +void b2WheelJoint::Dump() +{ + // FLT_DECIMAL_DIG == 9 + + int32 indexA = m_bodyA->m_islandIndex; + int32 indexB = m_bodyB->m_islandIndex; + + b2Dump(" b2WheelJointDef jd;\n"); + b2Dump(" jd.bodyA = bodies[%d];\n", indexA); + b2Dump(" jd.bodyB = bodies[%d];\n", indexB); + b2Dump(" jd.collideConnected = bool(%d);\n", m_collideConnected); + b2Dump(" jd.localAnchorA.Set(%.9g, %.9g);\n", m_localAnchorA.x, m_localAnchorA.y); + b2Dump(" jd.localAnchorB.Set(%.9g, %.9g);\n", m_localAnchorB.x, m_localAnchorB.y); + b2Dump(" jd.localAxisA.Set(%.9g, %.9g);\n", m_localXAxisA.x, m_localXAxisA.y); + b2Dump(" jd.enableMotor = bool(%d);\n", m_enableMotor); + b2Dump(" jd.motorSpeed = %.9g;\n", m_motorSpeed); + b2Dump(" jd.maxMotorTorque = %.9g;\n", m_maxMotorTorque); + b2Dump(" jd.stiffness = %.9g;\n", m_stiffness); + b2Dump(" jd.damping = %.9g;\n", m_damping); + b2Dump(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); +} + +/// +void b2WheelJoint::Draw(b2Draw* draw) const +{ + const b2Transform& xfA = m_bodyA->GetTransform(); + const b2Transform& xfB = m_bodyB->GetTransform(); + b2Vec2 pA = b2Mul(xfA, m_localAnchorA); + b2Vec2 pB = b2Mul(xfB, m_localAnchorB); + + b2Vec2 axis = b2Mul(xfA.q, m_localXAxisA); + + b2Color c1(0.7f, 0.7f, 0.7f); + b2Color c2(0.3f, 0.9f, 0.3f); + b2Color c3(0.9f, 0.3f, 0.3f); + b2Color c4(0.3f, 0.3f, 0.9f); + b2Color c5(0.4f, 0.4f, 0.4f); + + draw->DrawSegment(pA, pB, c5); + + if (m_enableLimit) + { + b2Vec2 lower = pA + m_lowerTranslation * axis; + b2Vec2 upper = pA + m_upperTranslation * axis; + b2Vec2 perp = b2Mul(xfA.q, m_localYAxisA); + draw->DrawSegment(lower, upper, c1); + draw->DrawSegment(lower - 0.5f * perp, lower + 0.5f * perp, c2); + draw->DrawSegment(upper - 0.5f * perp, upper + 0.5f * perp, c3); + } + else + { + draw->DrawSegment(pA - 1.0f * axis, pA + 1.0f * axis, c1); + } + + draw->DrawPoint(pA, 5.0f, c1); + draw->DrawPoint(pB, 5.0f, c4); +} diff --git a/src/libraries/Box2D/Dynamics/b2World.cpp b/src/libraries/Box2D/Dynamics/b2_world.cpp similarity index 82% rename from src/libraries/Box2D/Dynamics/b2World.cpp rename to src/libraries/Box2D/Dynamics/b2_world.cpp index c6cf2957b..1a0f79131 100644 --- a/src/libraries/Box2D/Dynamics/b2World.cpp +++ b/src/libraries/Box2D/Dynamics/b2_world.cpp @@ -1,46 +1,52 @@ -/* -* 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. -*/ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "b2_contact_solver.h" +#include "b2_island.h" + +#include "box2d/b2_body.h" +#include "box2d/b2_broad_phase.h" +#include "box2d/b2_chain_shape.h" +#include "box2d/b2_circle_shape.h" +#include "box2d/b2_collision.h" +#include "box2d/b2_contact.h" +#include "box2d/b2_draw.h" +#include "box2d/b2_edge_shape.h" +#include "box2d/b2_fixture.h" +#include "box2d/b2_polygon_shape.h" +#include "box2d/b2_pulley_joint.h" +#include "box2d/b2_time_of_impact.h" +#include "box2d/b2_timer.h" +#include "box2d/b2_world.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include b2World::b2World(const b2Vec2& gravity) { - m_destructionListener = NULL; - g_debugDraw = NULL; + m_destructionListener = nullptr; + m_debugDraw = nullptr; - m_bodyList = NULL; - m_jointList = NULL; + m_bodyList = nullptr; + m_jointList = nullptr; m_bodyCount = 0; m_jointCount = 0; @@ -54,7 +60,9 @@ b2World::b2World(const b2Vec2& gravity) m_allowSleep = true; m_gravity = gravity; - m_flags = e_clearForces; + m_newContacts = false; + m_locked = false; + m_clearForces = true; m_inv_dt0 = 0.0f; @@ -101,7 +109,7 @@ void b2World::SetContactListener(b2ContactListener* listener) void b2World::SetDebugDraw(b2Draw* debugDraw) { - g_debugDraw = debugDraw; + m_debugDraw = debugDraw; } b2Body* b2World::CreateBody(const b2BodyDef* def) @@ -109,14 +117,14 @@ b2Body* b2World::CreateBody(const b2BodyDef* def) b2Assert(IsLocked() == false); if (IsLocked()) { - return NULL; + 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 = NULL; + b->m_prev = nullptr; b->m_next = m_bodyList; if (m_bodyList) { @@ -153,7 +161,7 @@ void b2World::DestroyBody(b2Body* b) b->m_jointList = je; } - b->m_jointList = NULL; + b->m_jointList = nullptr; // Delete the attached contacts. b2ContactEdge* ce = b->m_contactList; @@ -163,7 +171,7 @@ void b2World::DestroyBody(b2Body* b) ce = ce->next; m_contactManager.Destroy(ce0->contact); } - b->m_contactList = NULL; + b->m_contactList = nullptr; // Delete the attached fixtures. This destroys broad-phase proxies. b2Fixture* f = b->m_fixtureList; @@ -185,7 +193,7 @@ void b2World::DestroyBody(b2Body* b) b->m_fixtureList = f; b->m_fixtureCount -= 1; } - b->m_fixtureList = NULL; + b->m_fixtureList = nullptr; b->m_fixtureCount = 0; // Remove world body list. @@ -214,13 +222,13 @@ b2Joint* b2World::CreateJoint(const b2JointDef* def) b2Assert(IsLocked() == false); if (IsLocked()) { - return NULL; + return nullptr; } b2Joint* j = b2Joint::Create(def, &m_blockAllocator); // Connect to the world list. - j->m_prev = NULL; + j->m_prev = nullptr; j->m_next = m_jointList; if (m_jointList) { @@ -232,14 +240,14 @@ b2Joint* b2World::CreateJoint(const b2JointDef* def) // Connect to the bodies' doubly linked lists. j->m_edgeA.joint = j; j->m_edgeA.other = j->m_bodyB; - j->m_edgeA.prev = NULL; + 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 = NULL; + 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; @@ -319,8 +327,8 @@ void b2World::DestroyJoint(b2Joint* j) bodyA->m_jointList = j->m_edgeA.next; } - j->m_edgeA.prev = NULL; - j->m_edgeA.next = NULL; + j->m_edgeA.prev = nullptr; + j->m_edgeA.next = nullptr; // Remove from body 2 if (j->m_edgeB.prev) @@ -338,8 +346,8 @@ void b2World::DestroyJoint(b2Joint* j) bodyB->m_jointList = j->m_edgeB.next; } - j->m_edgeB.prev = NULL; - j->m_edgeB.next = NULL; + j->m_edgeB.prev = nullptr; + j->m_edgeB.next = nullptr; b2Joint::Destroy(j, &m_blockAllocator); @@ -420,7 +428,7 @@ void b2World::Solve(const b2TimeStep& step) continue; } - if (seed->IsAwake() == false || seed->IsActive() == false) + if (seed->IsAwake() == false || seed->IsEnabled() == false) { continue; } @@ -442,12 +450,9 @@ void b2World::Solve(const b2TimeStep& step) { // Grab the next body off the stack and add it to the island. b2Body* b = stack[--stackCount]; - b2Assert(b->IsActive() == true); + b2Assert(b->IsEnabled() == true); island.Add(b); - // Make sure the body is awake. - b->SetAwake(true); - // To keep islands as small as possible, we don't // propagate islands across static bodies. if (b->GetType() == b2_staticBody) @@ -455,6 +460,9 @@ void b2World::Solve(const b2TimeStep& step) continue; } + // Make sure the body is awake (without resetting sleep timer). + b->m_flags |= b2Body::e_awakeFlag; + // Search all contacts connected to this body. for (b2ContactEdge* ce = b->m_contactList; ce; ce = ce->next) { @@ -507,8 +515,8 @@ void b2World::Solve(const b2TimeStep& step) b2Body* other = je->other; - // Don't simulate joints connected to inactive bodies. - if (other->IsActive() == false) + // Don't simulate joints connected to diabled bodies. + if (other->IsEnabled() == false) { continue; } @@ -599,8 +607,8 @@ void b2World::SolveTOI(const b2TimeStep& step) for (;;) { // Find the first TOI. - b2Contact* minContact = NULL; - float32 minAlpha = 1.0f; + b2Contact* minContact = nullptr; + float minAlpha = 1.0f; for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next) { @@ -616,7 +624,7 @@ void b2World::SolveTOI(const b2TimeStep& step) continue; } - float32 alpha = 1.0f; + float alpha = 1.0f; if (c->m_flags & b2Contact::e_toiFlag) { // This contact has a valid cached TOI. @@ -660,7 +668,7 @@ void b2World::SolveTOI(const b2TimeStep& step) // Compute the TOI for this contact. // Put the sweeps onto the same time interval. - float32 alpha0 = bA->m_sweep.alpha0; + float alpha0 = bA->m_sweep.alpha0; if (bA->m_sweep.alpha0 < bB->m_sweep.alpha0) { @@ -690,7 +698,7 @@ void b2World::SolveTOI(const b2TimeStep& step) b2TimeOfImpact(&output, &input); // Beta is the fraction of the remaining portion of the . - float32 beta = output.t; + float beta = output.t; if (output.state == b2TOIOutput::e_touching) { alpha = b2Min(alpha0 + (1.0f - alpha0) * beta, 1.0f); @@ -712,7 +720,7 @@ void b2World::SolveTOI(const b2TimeStep& step) } } - if (minContact == NULL || 1.0f - 10.0f * b2_epsilon < minAlpha) + if (minContact == nullptr || 1.0f - 10.0f * b2_epsilon < minAlpha) { // No more TOI events. Done! m_stepComplete = true; @@ -894,18 +902,18 @@ void b2World::SolveTOI(const b2TimeStep& step) } } -void b2World::Step(float32 dt, int32 velocityIterations, int32 positionIterations) +void b2World::Step(float dt, int32 velocityIterations, int32 positionIterations) { b2Timer stepTimer; // If new fixtures were added, we need to find the new contacts. - if (m_flags & e_newFixture) + if (m_newContacts) { m_contactManager.FindNewContacts(); - m_flags &= ~e_newFixture; + m_newContacts = false; } - m_flags |= e_locked; + m_locked = true; b2TimeStep step; step.dt = dt; @@ -952,12 +960,12 @@ void b2World::Step(float32 dt, int32 velocityIterations, int32 positionIteration m_inv_dt0 = step.inv_dt; } - if (m_flags & e_clearForces) + if (m_clearForces) { ClearForces(); } - m_flags &= ~e_locked; + m_locked = false; m_profile.step = stepTimer.GetMilliseconds(); } @@ -993,7 +1001,7 @@ void b2World::QueryAABB(b2QueryCallback* callback, const b2AABB& aabb) const struct b2WorldRayCastWrapper { - float32 RayCastCallback(const b2RayCastInput& input, int32 proxyId) + float RayCastCallback(const b2RayCastInput& input, int32 proxyId) { void* userData = broadPhase->GetUserData(proxyId); b2FixtureProxy* proxy = (b2FixtureProxy*)userData; @@ -1004,7 +1012,7 @@ struct b2WorldRayCastWrapper if (hit) { - float32 fraction = output.fraction; + float fraction = output.fraction; b2Vec2 point = (1.0f - fraction) * input.p1 + fraction * input.p2; return callback->ReportFixture(fixture, point, output.normal, fraction); } @@ -1037,10 +1045,10 @@ void b2World::DrawShape(b2Fixture* fixture, const b2Transform& xf, const b2Color b2CircleShape* circle = (b2CircleShape*)fixture->GetShape(); b2Vec2 center = b2Mul(xf, circle->m_p); - float32 radius = circle->m_radius; + float radius = circle->m_radius; b2Vec2 axis = b2Mul(xf.q, b2Vec2(1.0f, 0.0f)); - g_debugDraw->DrawSolidCircle(center, radius, axis, color); + m_debugDraw->DrawSolidCircle(center, radius, axis, color); } break; @@ -1049,7 +1057,13 @@ void b2World::DrawShape(b2Fixture* fixture, const b2Transform& xf, const b2Color b2EdgeShape* edge = (b2EdgeShape*)fixture->GetShape(); b2Vec2 v1 = b2Mul(xf, edge->m_vertex1); b2Vec2 v2 = b2Mul(xf, edge->m_vertex2); - g_debugDraw->DrawSegment(v1, v2, color); + m_debugDraw->DrawSegment(v1, v2, color); + + if (edge->m_oneSided == false) + { + m_debugDraw->DrawPoint(v1, 4.0f, color); + m_debugDraw->DrawPoint(v2, 4.0f, color); + } } break; @@ -1063,8 +1077,7 @@ void b2World::DrawShape(b2Fixture* fixture, const b2Transform& xf, const b2Color for (int32 i = 1; i < count; ++i) { b2Vec2 v2 = b2Mul(xf, vertices[i]); - g_debugDraw->DrawSegment(v1, v2, color); - g_debugDraw->DrawCircle(v1, 0.05f, color); + m_debugDraw->DrawSegment(v1, v2, color); v1 = v2; } } @@ -1082,64 +1095,23 @@ void b2World::DrawShape(b2Fixture* fixture, const b2Transform& xf, const b2Color vertices[i] = b2Mul(xf, poly->m_vertices[i]); } - g_debugDraw->DrawSolidPolygon(vertices, vertexCount, color); + 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: - g_debugDraw->DrawSegment(p1, p2, color); - break; - - case e_pulleyJoint: - { - b2PulleyJoint* pulley = (b2PulleyJoint*)joint; - b2Vec2 s1 = pulley->GetGroundAnchorA(); - b2Vec2 s2 = pulley->GetGroundAnchorB(); - g_debugDraw->DrawSegment(s1, p1, color); - g_debugDraw->DrawSegment(s2, p2, color); - g_debugDraw->DrawSegment(s1, s2, color); - } - break; - - case e_mouseJoint: - // don't draw this - break; default: - g_debugDraw->DrawSegment(x1, p1, color); - g_debugDraw->DrawSegment(p1, p2, color); - g_debugDraw->DrawSegment(x2, p2, color); + break; } } -void b2World::DrawDebugData() +void b2World::DebugDraw() { - if (g_debugDraw == NULL) + if (m_debugDraw == nullptr) { return; } - uint32 flags = g_debugDraw->GetFlags(); + uint32 flags = m_debugDraw->GetFlags(); if (flags & b2Draw::e_shapeBit) { @@ -1148,7 +1120,12 @@ void b2World::DrawDebugData() const b2Transform& xf = b->GetTransform(); for (b2Fixture* f = b->GetFixtureList(); f; f = f->GetNext()) { - if (b->IsActive() == false) + if (b->GetType() == b2_dynamicBody && b->m_mass == 0.0f) + { + // Bad body + DrawShape(f, xf, b2Color(1.0f, 0.0f, 0.0f)); + } + else if (b->IsEnabled() == false) { DrawShape(f, xf, b2Color(0.5f, 0.5f, 0.3f)); } @@ -1176,7 +1153,7 @@ void b2World::DrawDebugData() { for (b2Joint* j = m_jointList; j; j = j->GetNext()) { - DrawJoint(j); + j->Draw(m_debugDraw); } } @@ -1185,13 +1162,14 @@ void b2World::DrawDebugData() 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(); + b2Fixture* fixtureA = c->GetFixtureA(); + b2Fixture* fixtureB = c->GetFixtureB(); + int32 indexA = c->GetChildIndexA(); + int32 indexB = c->GetChildIndexB(); + b2Vec2 cA = fixtureA->GetAABB(indexA).GetCenter(); + b2Vec2 cB = fixtureB->GetAABB(indexB).GetCenter(); - //b2Vec2 cA = fixtureA->GetAABB().GetCenter(); - //b2Vec2 cB = fixtureB->GetAABB().GetCenter(); - - //g_debugDraw->DrawSegment(cA, cB, color); + m_debugDraw->DrawSegment(cA, cB, color); } } @@ -1202,7 +1180,7 @@ void b2World::DrawDebugData() for (b2Body* b = m_bodyList; b; b = b->GetNext()) { - if (b->IsActive() == false) + if (b->IsEnabled() == false) { continue; } @@ -1219,7 +1197,7 @@ void b2World::DrawDebugData() vs[2].Set(aabb.upperBound.x, aabb.upperBound.y); vs[3].Set(aabb.lowerBound.x, aabb.upperBound.y); - g_debugDraw->DrawPolygon(vs, 4, color); + m_debugDraw->DrawPolygon(vs, 4, color); } } } @@ -1231,7 +1209,7 @@ void b2World::DrawDebugData() { b2Transform xf = b->GetTransform(); xf.p = b->GetWorldCenter(); - g_debugDraw->DrawTransform(xf); + m_debugDraw->DrawTransform(xf); } } } @@ -1251,15 +1229,15 @@ int32 b2World::GetTreeBalance() const return m_contactManager.m_broadPhase.GetTreeBalance(); } -float32 b2World::GetTreeQuality() const +float 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) + b2Assert(m_locked == false); + if (m_locked) { return; } @@ -1281,16 +1259,19 @@ void b2World::ShiftOrigin(const b2Vec2& newOrigin) void b2World::Dump() { - if ((m_flags & e_locked) == e_locked) + if (m_locked) { return; } - b2Log("b2Vec2 g(%.15lef, %.15lef);\n", m_gravity.x, m_gravity.y); - b2Log("m_world->SetGravity(g);\n"); + b2OpenDump("box2d_dump.inl"); + + b2Dump("b2Vec2 g(%.9g, %.9g);\n", m_gravity.x, m_gravity.y); + b2Dump("m_world->SetGravity(g);\n"); + + b2Dump("b2Body** bodies = (b2Body**)b2Alloc(%d * sizeof(b2Body*));\n", m_bodyCount); + b2Dump("b2Joint** joints = (b2Joint**)b2Alloc(%d * sizeof(b2Joint*));\n", m_jointCount); - 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) { @@ -1314,9 +1295,9 @@ void b2World::Dump() continue; } - b2Log("{\n"); + b2Dump("{\n"); j->Dump(); - b2Log("}\n"); + b2Dump("}\n"); } // Second pass on joints, only gear joints. @@ -1327,13 +1308,15 @@ void b2World::Dump() continue; } - b2Log("{\n"); + b2Dump("{\n"); j->Dump(); - b2Log("}\n"); + b2Dump("}\n"); } - b2Log("b2Free(joints);\n"); - b2Log("b2Free(bodies);\n"); - b2Log("joints = NULL;\n"); - b2Log("bodies = NULL;\n"); + b2Dump("b2Free(joints);\n"); + b2Dump("b2Free(bodies);\n"); + b2Dump("joints = nullptr;\n"); + b2Dump("bodies = nullptr;\n"); + + b2CloseDump(); } diff --git a/src/libraries/Box2D/Dynamics/b2_world_callbacks.cpp b/src/libraries/Box2D/Dynamics/b2_world_callbacks.cpp new file mode 100644 index 000000000..e1583e221 --- /dev/null +++ b/src/libraries/Box2D/Dynamics/b2_world_callbacks.cpp @@ -0,0 +1,40 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_fixture.h" +#include "box2d/b2_world_callbacks.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/libraries/Box2D/Rope/b2Rope.cpp b/src/libraries/Box2D/Rope/b2Rope.cpp deleted file mode 100644 index 7af3a6cf2..000000000 --- a/src/libraries/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 -#include - -b2Rope::b2Rope() -{ - m_count = 0; - m_ps = NULL; - m_p0s = NULL; - m_vs = NULL; - m_ims = NULL; - m_Ls = NULL; - m_as = NULL; - 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/libraries/Box2D/Rope/b2Rope.h b/src/libraries/Box2D/Rope/b2Rope.h deleted file mode 100644 index 246cf923f..000000000 --- a/src/libraries/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 - -class b2Draw; - -/// -struct b2RopeDef -{ - b2RopeDef() - { - vertices = NULL; - count = 0; - masses = NULL; - 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/libraries/Box2D/Rope/b2_rope.cpp b/src/libraries/Box2D/Rope/b2_rope.cpp new file mode 100644 index 000000000..511944814 --- /dev/null +++ b/src/libraries/Box2D/Rope/b2_rope.cpp @@ -0,0 +1,769 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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. + +#include "box2d/b2_draw.h" +#include "box2d/b2_rope.h" + +#include + +struct b2RopeStretch +{ + int32 i1, i2; + float invMass1, invMass2; + float L; + float lambda; + float spring; + float damper; +}; + +struct b2RopeBend +{ + int32 i1, i2, i3; + float invMass1, invMass2, invMass3; + float invEffectiveMass; + float lambda; + float L1, L2; + float alpha1, alpha2; + float spring; + float damper; +}; + +b2Rope::b2Rope() +{ + m_position.SetZero(); + m_count = 0; + m_stretchCount = 0; + m_bendCount = 0; + m_stretchConstraints = nullptr; + m_bendConstraints = nullptr; + m_bindPositions = nullptr; + m_ps = nullptr; + m_p0s = nullptr; + m_vs = nullptr; + m_invMasses = nullptr; + m_gravity.SetZero(); +} + +b2Rope::~b2Rope() +{ + b2Free(m_stretchConstraints); + b2Free(m_bendConstraints); + b2Free(m_bindPositions); + b2Free(m_ps); + b2Free(m_p0s); + b2Free(m_vs); + b2Free(m_invMasses); +} + +void b2Rope::Create(const b2RopeDef& def) +{ + b2Assert(def.count >= 3); + m_position = def.position; + m_count = def.count; + m_bindPositions = (b2Vec2*)b2Alloc(m_count * sizeof(b2Vec2)); + 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_invMasses = (float*)b2Alloc(m_count * sizeof(float)); + + for (int32 i = 0; i < m_count; ++i) + { + m_bindPositions[i] = def.vertices[i]; + m_ps[i] = def.vertices[i] + m_position; + m_p0s[i] = def.vertices[i] + m_position; + m_vs[i].SetZero(); + + float m = def.masses[i]; + if (m > 0.0f) + { + m_invMasses[i] = 1.0f / m; + } + else + { + m_invMasses[i] = 0.0f; + } + } + + m_stretchCount = m_count - 1; + m_bendCount = m_count - 2; + + m_stretchConstraints = (b2RopeStretch*)b2Alloc(m_stretchCount * sizeof(b2RopeStretch)); + m_bendConstraints = (b2RopeBend*)b2Alloc(m_bendCount * sizeof(b2RopeBend)); + + for (int32 i = 0; i < m_stretchCount; ++i) + { + b2RopeStretch& c = m_stretchConstraints[i]; + + b2Vec2 p1 = m_ps[i]; + b2Vec2 p2 = m_ps[i+1]; + + c.i1 = i; + c.i2 = i + 1; + c.L = b2Distance(p1, p2); + c.invMass1 = m_invMasses[i]; + c.invMass2 = m_invMasses[i + 1]; + c.lambda = 0.0f; + c.damper = 0.0f; + c.spring = 0.0f; + } + + for (int32 i = 0; i < m_bendCount; ++i) + { + b2RopeBend& c = m_bendConstraints[i]; + + b2Vec2 p1 = m_ps[i]; + b2Vec2 p2 = m_ps[i + 1]; + b2Vec2 p3 = m_ps[i + 2]; + + c.i1 = i; + c.i2 = i + 1; + c.i3 = i + 2; + c.invMass1 = m_invMasses[i]; + c.invMass2 = m_invMasses[i + 1]; + c.invMass3 = m_invMasses[i + 2]; + c.invEffectiveMass = 0.0f; + c.L1 = b2Distance(p1, p2); + c.L2 = b2Distance(p2, p3); + c.lambda = 0.0f; + + // Pre-compute effective mass (TODO use flattened config) + b2Vec2 e1 = p2 - p1; + b2Vec2 e2 = p3 - p2; + float L1sqr = e1.LengthSquared(); + float L2sqr = e2.LengthSquared(); + + if (L1sqr * L2sqr == 0.0f) + { + continue; + } + + b2Vec2 Jd1 = (-1.0f / L1sqr) * e1.Skew(); + b2Vec2 Jd2 = (1.0f / L2sqr) * e2.Skew(); + + b2Vec2 J1 = -Jd1; + b2Vec2 J2 = Jd1 - Jd2; + b2Vec2 J3 = Jd2; + + c.invEffectiveMass = c.invMass1 * b2Dot(J1, J1) + c.invMass2 * b2Dot(J2, J2) + c.invMass3 * b2Dot(J3, J3); + + b2Vec2 r = p3 - p1; + + float rr = r.LengthSquared(); + if (rr == 0.0f) + { + continue; + } + + // a1 = h2 / (h1 + h2) + // a2 = h1 / (h1 + h2) + c.alpha1 = b2Dot(e2, r) / rr; + c.alpha2 = b2Dot(e1, r) / rr; + } + + m_gravity = def.gravity; + + SetTuning(def.tuning); +} + +void b2Rope::SetTuning(const b2RopeTuning& tuning) +{ + m_tuning = tuning; + + // Pre-compute spring and damper values based on tuning + + const float bendOmega = 2.0f * b2_pi * m_tuning.bendHertz; + + for (int32 i = 0; i < m_bendCount; ++i) + { + b2RopeBend& c = m_bendConstraints[i]; + + float L1sqr = c.L1 * c.L1; + float L2sqr = c.L2 * c.L2; + + if (L1sqr * L2sqr == 0.0f) + { + c.spring = 0.0f; + c.damper = 0.0f; + continue; + } + + // Flatten the triangle formed by the two edges + float J2 = 1.0f / c.L1 + 1.0f / c.L2; + float sum = c.invMass1 / L1sqr + c.invMass2 * J2 * J2 + c.invMass3 / L2sqr; + if (sum == 0.0f) + { + c.spring = 0.0f; + c.damper = 0.0f; + continue; + } + + float mass = 1.0f / sum; + + c.spring = mass * bendOmega * bendOmega; + c.damper = 2.0f * mass * m_tuning.bendDamping * bendOmega; + } + + const float stretchOmega = 2.0f * b2_pi * m_tuning.stretchHertz; + + for (int32 i = 0; i < m_stretchCount; ++i) + { + b2RopeStretch& c = m_stretchConstraints[i]; + + float sum = c.invMass1 + c.invMass2; + if (sum == 0.0f) + { + continue; + } + + float mass = 1.0f / sum; + + c.spring = mass * stretchOmega * stretchOmega; + c.damper = 2.0f * mass * m_tuning.stretchDamping * stretchOmega; + } +} + +void b2Rope::Step(float dt, int32 iterations, const b2Vec2& position) +{ + if (dt == 0.0) + { + return; + } + + const float inv_dt = 1.0f / dt; + float d = expf(- dt * m_tuning.damping); + + // Apply gravity and damping + for (int32 i = 0; i < m_count; ++i) + { + if (m_invMasses[i] > 0.0f) + { + m_vs[i] *= d; + m_vs[i] += dt * m_gravity; + } + else + { + m_vs[i] = inv_dt * (m_bindPositions[i] + position - m_p0s[i]); + } + } + + // Apply bending spring + if (m_tuning.bendingModel == b2_springAngleBendingModel) + { + ApplyBendForces(dt); + } + + for (int32 i = 0; i < m_bendCount; ++i) + { + m_bendConstraints[i].lambda = 0.0f; + } + + for (int32 i = 0; i < m_stretchCount; ++i) + { + m_stretchConstraints[i].lambda = 0.0f; + } + + // Update position + for (int32 i = 0; i < m_count; ++i) + { + m_ps[i] += dt * m_vs[i]; + } + + // Solve constraints + for (int32 i = 0; i < iterations; ++i) + { + if (m_tuning.bendingModel == b2_pbdAngleBendingModel) + { + SolveBend_PBD_Angle(); + } + else if (m_tuning.bendingModel == b2_xpbdAngleBendingModel) + { + SolveBend_XPBD_Angle(dt); + } + else if (m_tuning.bendingModel == b2_pbdDistanceBendingModel) + { + SolveBend_PBD_Distance(); + } + else if (m_tuning.bendingModel == b2_pbdHeightBendingModel) + { + SolveBend_PBD_Height(); + } + + if (m_tuning.stretchingModel == b2_pbdStretchingModel) + { + SolveStretch_PBD(); + } + else if (m_tuning.stretchingModel == b2_xpbdStretchingModel) + { + SolveStretch_XPBD(dt); + } + } + + // Constrain velocity + for (int32 i = 0; i < m_count; ++i) + { + m_vs[i] = inv_dt * (m_ps[i] - m_p0s[i]); + m_p0s[i] = m_ps[i]; + } +} + +void b2Rope::Reset(const b2Vec2& position) +{ + m_position = position; + + for (int32 i = 0; i < m_count; ++i) + { + m_ps[i] = m_bindPositions[i] + m_position; + m_p0s[i] = m_bindPositions[i] + m_position; + m_vs[i].SetZero(); + } + + for (int32 i = 0; i < m_bendCount; ++i) + { + m_bendConstraints[i].lambda = 0.0f; + } + + for (int32 i = 0; i < m_stretchCount; ++i) + { + m_stretchConstraints[i].lambda = 0.0f; + } +} + +void b2Rope::SolveStretch_PBD() +{ + const float stiffness = m_tuning.stretchStiffness; + + for (int32 i = 0; i < m_stretchCount; ++i) + { + const b2RopeStretch& c = m_stretchConstraints[i]; + + b2Vec2 p1 = m_ps[c.i1]; + b2Vec2 p2 = m_ps[c.i2]; + + b2Vec2 d = p2 - p1; + float L = d.Normalize(); + + float sum = c.invMass1 + c.invMass2; + if (sum == 0.0f) + { + continue; + } + + float s1 = c.invMass1 / sum; + float s2 = c.invMass2 / sum; + + p1 -= stiffness * s1 * (c.L - L) * d; + p2 += stiffness * s2 * (c.L - L) * d; + + m_ps[c.i1] = p1; + m_ps[c.i2] = p2; + } +} + +void b2Rope::SolveStretch_XPBD(float dt) +{ + b2Assert(dt > 0.0f); + + for (int32 i = 0; i < m_stretchCount; ++i) + { + b2RopeStretch& c = m_stretchConstraints[i]; + + b2Vec2 p1 = m_ps[c.i1]; + b2Vec2 p2 = m_ps[c.i2]; + + b2Vec2 dp1 = p1 - m_p0s[c.i1]; + b2Vec2 dp2 = p2 - m_p0s[c.i2]; + + b2Vec2 u = p2 - p1; + float L = u.Normalize(); + + b2Vec2 J1 = -u; + b2Vec2 J2 = u; + + float sum = c.invMass1 + c.invMass2; + if (sum == 0.0f) + { + continue; + } + + const float alpha = 1.0f / (c.spring * dt * dt); // 1 / kg + const float beta = dt * dt * c.damper; // kg * s + const float sigma = alpha * beta / dt; // non-dimensional + float C = L - c.L; + + // This is using the initial velocities + float Cdot = b2Dot(J1, dp1) + b2Dot(J2, dp2); + + float B = C + alpha * c.lambda + sigma * Cdot; + float sum2 = (1.0f + sigma) * sum + alpha; + + float impulse = -B / sum2; + + p1 += (c.invMass1 * impulse) * J1; + p2 += (c.invMass2 * impulse) * J2; + + m_ps[c.i1] = p1; + m_ps[c.i2] = p2; + c.lambda += impulse; + } +} + +void b2Rope::SolveBend_PBD_Angle() +{ + const float stiffness = m_tuning.bendStiffness; + + for (int32 i = 0; i < m_bendCount; ++i) + { + const b2RopeBend& c = m_bendConstraints[i]; + + b2Vec2 p1 = m_ps[c.i1]; + b2Vec2 p2 = m_ps[c.i2]; + b2Vec2 p3 = m_ps[c.i3]; + + b2Vec2 d1 = p2 - p1; + b2Vec2 d2 = p3 - p2; + float a = b2Cross(d1, d2); + float b = b2Dot(d1, d2); + + float angle = b2Atan2(a, b); + + float L1sqr, L2sqr; + + if (m_tuning.isometric) + { + L1sqr = c.L1 * c.L1; + L2sqr = c.L2 * c.L2; + } + else + { + L1sqr = d1.LengthSquared(); + L2sqr = d2.LengthSquared(); + } + + if (L1sqr * L2sqr == 0.0f) + { + continue; + } + + b2Vec2 Jd1 = (-1.0f / L1sqr) * d1.Skew(); + b2Vec2 Jd2 = (1.0f / L2sqr) * d2.Skew(); + + b2Vec2 J1 = -Jd1; + b2Vec2 J2 = Jd1 - Jd2; + b2Vec2 J3 = Jd2; + + float sum; + if (m_tuning.fixedEffectiveMass) + { + sum = c.invEffectiveMass; + } + else + { + sum = c.invMass1 * b2Dot(J1, J1) + c.invMass2 * b2Dot(J2, J2) + c.invMass3 * b2Dot(J3, J3); + } + + if (sum == 0.0f) + { + sum = c.invEffectiveMass; + } + + float impulse = -stiffness * angle / sum; + + p1 += (c.invMass1 * impulse) * J1; + p2 += (c.invMass2 * impulse) * J2; + p3 += (c.invMass3 * impulse) * J3; + + m_ps[c.i1] = p1; + m_ps[c.i2] = p2; + m_ps[c.i3] = p3; + } +} + +void b2Rope::SolveBend_XPBD_Angle(float dt) +{ + b2Assert(dt > 0.0f); + + for (int32 i = 0; i < m_bendCount; ++i) + { + b2RopeBend& c = m_bendConstraints[i]; + + b2Vec2 p1 = m_ps[c.i1]; + b2Vec2 p2 = m_ps[c.i2]; + b2Vec2 p3 = m_ps[c.i3]; + + b2Vec2 dp1 = p1 - m_p0s[c.i1]; + b2Vec2 dp2 = p2 - m_p0s[c.i2]; + b2Vec2 dp3 = p3 - m_p0s[c.i3]; + + b2Vec2 d1 = p2 - p1; + b2Vec2 d2 = p3 - p2; + + float L1sqr, L2sqr; + + if (m_tuning.isometric) + { + L1sqr = c.L1 * c.L1; + L2sqr = c.L2 * c.L2; + } + else + { + L1sqr = d1.LengthSquared(); + L2sqr = d2.LengthSquared(); + } + + if (L1sqr * L2sqr == 0.0f) + { + continue; + } + + float a = b2Cross(d1, d2); + float b = b2Dot(d1, d2); + + float 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; + + float sum; + if (m_tuning.fixedEffectiveMass) + { + sum = c.invEffectiveMass; + } + else + { + sum = c.invMass1 * b2Dot(J1, J1) + c.invMass2 * b2Dot(J2, J2) + c.invMass3 * b2Dot(J3, J3); + } + + if (sum == 0.0f) + { + continue; + } + + const float alpha = 1.0f / (c.spring * dt * dt); + const float beta = dt * dt * c.damper; + const float sigma = alpha * beta / dt; + float C = angle; + + // This is using the initial velocities + float Cdot = b2Dot(J1, dp1) + b2Dot(J2, dp2) + b2Dot(J3, dp3); + + float B = C + alpha * c.lambda + sigma * Cdot; + float sum2 = (1.0f + sigma) * sum + alpha; + + float impulse = -B / sum2; + + p1 += (c.invMass1 * impulse) * J1; + p2 += (c.invMass2 * impulse) * J2; + p3 += (c.invMass3 * impulse) * J3; + + m_ps[c.i1] = p1; + m_ps[c.i2] = p2; + m_ps[c.i3] = p3; + c.lambda += impulse; + } +} + +void b2Rope::ApplyBendForces(float dt) +{ + // omega = 2 * pi * hz + const float omega = 2.0f * b2_pi * m_tuning.bendHertz; + + for (int32 i = 0; i < m_bendCount; ++i) + { + const b2RopeBend& c = m_bendConstraints[i]; + + b2Vec2 p1 = m_ps[c.i1]; + b2Vec2 p2 = m_ps[c.i2]; + b2Vec2 p3 = m_ps[c.i3]; + + b2Vec2 v1 = m_vs[c.i1]; + b2Vec2 v2 = m_vs[c.i2]; + b2Vec2 v3 = m_vs[c.i3]; + + b2Vec2 d1 = p2 - p1; + b2Vec2 d2 = p3 - p2; + + float L1sqr, L2sqr; + + if (m_tuning.isometric) + { + L1sqr = c.L1 * c.L1; + L2sqr = c.L2 * c.L2; + } + else + { + L1sqr = d1.LengthSquared(); + L2sqr = d2.LengthSquared(); + } + + if (L1sqr * L2sqr == 0.0f) + { + continue; + } + + float a = b2Cross(d1, d2); + float b = b2Dot(d1, d2); + + float 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; + + float sum; + if (m_tuning.fixedEffectiveMass) + { + sum = c.invEffectiveMass; + } + else + { + sum = c.invMass1 * b2Dot(J1, J1) + c.invMass2 * b2Dot(J2, J2) + c.invMass3 * b2Dot(J3, J3); + } + + if (sum == 0.0f) + { + continue; + } + + float mass = 1.0f / sum; + + const float spring = mass * omega * omega; + const float damper = 2.0f * mass * m_tuning.bendDamping * omega; + + float C = angle; + float Cdot = b2Dot(J1, v1) + b2Dot(J2, v2) + b2Dot(J3, v3); + + float impulse = -dt * (spring * C + damper * Cdot); + + m_vs[c.i1] += (c.invMass1 * impulse) * J1; + m_vs[c.i2] += (c.invMass2 * impulse) * J2; + m_vs[c.i3] += (c.invMass3 * impulse) * J3; + } +} + +void b2Rope::SolveBend_PBD_Distance() +{ + const float stiffness = m_tuning.bendStiffness; + + for (int32 i = 0; i < m_bendCount; ++i) + { + const b2RopeBend& c = m_bendConstraints[i]; + + int32 i1 = c.i1; + int32 i2 = c.i3; + + b2Vec2 p1 = m_ps[i1]; + b2Vec2 p2 = m_ps[i2]; + + b2Vec2 d = p2 - p1; + float L = d.Normalize(); + + float sum = c.invMass1 + c.invMass3; + if (sum == 0.0f) + { + continue; + } + + float s1 = c.invMass1 / sum; + float s2 = c.invMass3 / sum; + + p1 -= stiffness * s1 * (c.L1 + c.L2 - L) * d; + p2 += stiffness * s2 * (c.L1 + c.L2 - L) * d; + + m_ps[i1] = p1; + m_ps[i2] = p2; + } +} + +// Constraint based implementation of: +// P. Volino: Simple Linear Bending Stiffness in Particle Systems +void b2Rope::SolveBend_PBD_Height() +{ + const float stiffness = m_tuning.bendStiffness; + + for (int32 i = 0; i < m_bendCount; ++i) + { + const b2RopeBend& c = m_bendConstraints[i]; + + b2Vec2 p1 = m_ps[c.i1]; + b2Vec2 p2 = m_ps[c.i2]; + b2Vec2 p3 = m_ps[c.i3]; + + // Barycentric coordinates are held constant + b2Vec2 d = c.alpha1 * p1 + c.alpha2 * p3 - p2; + float dLen = d.Length(); + + if (dLen == 0.0f) + { + continue; + } + + b2Vec2 dHat = (1.0f / dLen) * d; + + b2Vec2 J1 = c.alpha1 * dHat; + b2Vec2 J2 = -dHat; + b2Vec2 J3 = c.alpha2 * dHat; + + float sum = c.invMass1 * c.alpha1 * c.alpha1 + c.invMass2 + c.invMass3 * c.alpha2 * c.alpha2; + + if (sum == 0.0f) + { + continue; + } + + float C = dLen; + float mass = 1.0f / sum; + float impulse = -stiffness * mass * C; + + p1 += (c.invMass1 * impulse) * J1; + p2 += (c.invMass2 * impulse) * J2; + p3 += (c.invMass3 * impulse) * J3; + + m_ps[c.i1] = p1; + m_ps[c.i2] = p2; + m_ps[c.i3] = p3; + } +} + +void b2Rope::Draw(b2Draw* draw) const +{ + b2Color c(0.4f, 0.5f, 0.7f); + b2Color pg(0.1f, 0.8f, 0.1f); + b2Color pd(0.7f, 0.2f, 0.4f); + + for (int32 i = 0; i < m_count - 1; ++i) + { + draw->DrawSegment(m_ps[i], m_ps[i+1], c); + + const b2Color& pc = m_invMasses[i] > 0.0f ? pd : pg; + draw->DrawPoint(m_ps[i], 5.0f, pc); + } + + const b2Color& pc = m_invMasses[m_count - 1] > 0.0f ? pd : pg; + draw->DrawPoint(m_ps[m_count - 1], 5.0f, pc); +} diff --git a/src/libraries/Box2D/b2_block_allocator.h b/src/libraries/Box2D/b2_block_allocator.h new file mode 100644 index 000000000..48957343e --- /dev/null +++ b/src/libraries/Box2D/b2_block_allocator.h @@ -0,0 +1,59 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_BLOCK_ALLOCATOR_H +#define B2_BLOCK_ALLOCATOR_H + +#include "box2d/b2_settings.h" + +const int32 b2_blockSizeCount = 14; + +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_blockSizeCount]; +}; + +#endif diff --git a/src/libraries/Box2D/Dynamics/b2Body.h b/src/libraries/Box2D/b2_body.h similarity index 80% rename from src/libraries/Box2D/Dynamics/b2Body.h rename to src/libraries/Box2D/b2_body.h index 24bae6403..6ba8574de 100644 --- a/src/libraries/Box2D/Dynamics/b2Body.h +++ b/src/libraries/Box2D/b2_body.h @@ -1,27 +1,30 @@ -/* -* 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. -*/ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_BODY_H #define B2_BODY_H -#include -#include -#include +#include "b2_math.h" +#include "b2_shape.h" class b2Fixture; class b2Joint; @@ -53,7 +56,7 @@ struct b2BodyDef /// This constructor sets the body definition default values. b2BodyDef() { - userData = NULL; + userData = nullptr; position.Set(0.0f, 0.0f); angle = 0.0f; linearVelocity.Set(0.0f, 0.0f); @@ -65,7 +68,7 @@ struct b2BodyDef fixedRotation = false; bullet = false; type = b2_staticBody; - active = true; + enabled = true; gravityScale = 1.0f; } @@ -78,23 +81,25 @@ struct b2BodyDef b2Vec2 position; /// The world angle of the body in radians. - float32 angle; + float angle; /// The linear velocity of the body's origin in world co-ordinates. b2Vec2 linearVelocity; /// The angular velocity of the body. - float32 angularVelocity; + float 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. - float32 linearDamping; + /// Units are 1/time + float 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. - float32 angularDamping; + /// Units are 1/time + float angularDamping; /// Set this flag to false if this body should never fall asleep. Note that /// this increases CPU usage. @@ -112,14 +117,14 @@ struct b2BodyDef /// @warning You should use this flag sparingly since it increases processing time. bool bullet; - /// Does this body start out active? - bool active; + /// Does this body start out enabled? + bool enabled; /// Use this to store application specific body data. void* userData; /// Scale the gravity applied to this body. - float32 gravityScale; + float gravityScale; }; /// A rigid body. These are created via b2World::CreateBody. @@ -142,7 +147,7 @@ public: /// @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); + b2Fixture* CreateFixture(const b2Shape* shape, float density); /// Destroy a fixture. This removes the fixture from the broad-phase and /// destroys all contacts associated with this fixture. This will @@ -158,7 +163,7 @@ public: /// 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); + void SetTransform(const b2Vec2& position, float angle); /// Get the body transform for the body's origin. /// @return the world transform of the body's origin. @@ -170,7 +175,7 @@ public: /// Get the angle in radians. /// @return the current world rotation angle in radians. - float32 GetAngle() const; + float GetAngle() const; /// Get the world position of the center of mass. const b2Vec2& GetWorldCenter() const; @@ -188,11 +193,11 @@ public: /// Set the angular velocity. /// @param omega the new angular velocity in radians/second. - void SetAngularVelocity(float32 omega); + void SetAngularVelocity(float omega); /// Get the angular velocity. /// @return the angular velocity in radians/second. - float32 GetAngularVelocity() const; + float 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 @@ -209,10 +214,9 @@ public: /// Apply a torque. This affects the angular velocity /// without affecting the linear velocity of the center of mass. - /// This wakes up the body. /// @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); + void ApplyTorque(float 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 @@ -222,18 +226,23 @@ public: /// @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); + void ApplyAngularImpulse(float impulse, bool wake); /// Get the total mass of the body. /// @return the mass, usually in kilograms (kg). - float32 GetMass() const; + float 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; + float GetInertia() const; /// Get the mass data of the body. /// @return a struct containing the mass, inertia and center of the body. @@ -243,7 +252,7 @@ public: /// 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. + /// @param data the mass properties. void SetMassData(const b2MassData* data); /// This resets the mass properties to the sum of the mass properties of the fixtures. @@ -262,42 +271,42 @@ public: 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. + /// @param worldPoint 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. + /// @param worldVector 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. + /// @param worldPoint 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. + /// @param localPoint 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; + float GetLinearDamping() const; /// Set the linear damping of the body. - void SetLinearDamping(float32 linearDamping); + void SetLinearDamping(float linearDamping); /// Get the angular damping of the body. - float32 GetAngularDamping() const; + float GetAngularDamping() const; /// Set the angular damping of the body. - void SetAngularDamping(float32 angularDamping); + void SetAngularDamping(float angularDamping); /// Get the gravity scale of the body. - float32 GetGravityScale() const; + float GetGravityScale() const; /// Set the gravity scale of the body. - void SetGravityScale(float32 scale); + void SetGravityScale(float scale); /// Set the type of this body. This may alter the mass and velocity. void SetType(b2BodyType type); @@ -327,23 +336,22 @@ public: /// @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. + /// Allow a body to be disabled. A disabled 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 + /// to create/destroy fixtures and joints on disabled bodies. + /// Fixtures on a disabled body are implicitly disabled 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 + /// Joints connected to a disabled body are implicitly disabled. + /// An diabled body is still owned by a b2World object and remains /// in the body list. - void SetActive(bool flag); + void SetEnabled(bool flag); /// Get the active state of the body. - bool IsActive() const; + bool IsEnabled() const; /// Set this body to have fixed rotation. This causes the mass /// to be reset. @@ -380,7 +388,7 @@ public: b2World* GetWorld(); const b2World* GetWorld() const; - /// Dump this body to a log file + /// Dump this body to a file void Dump(); private: @@ -411,7 +419,7 @@ private: e_autoSleepFlag = 0x0004, e_bulletFlag = 0x0008, e_fixedRotationFlag = 0x0010, - e_activeFlag = 0x0020, + e_enabledFlag = 0x0020, e_toiFlag = 0x0040 }; @@ -425,7 +433,7 @@ private: // It may lie, depending on the collideConnected flag. bool ShouldCollide(const b2Body* other) const; - void Advance(float32 t); + void Advance(float t); b2BodyType m_type; @@ -437,10 +445,10 @@ private: b2Sweep m_sweep; // the swept motion for CCD b2Vec2 m_linearVelocity; - float32 m_angularVelocity; + float m_angularVelocity; b2Vec2 m_force; - float32 m_torque; + float m_torque; b2World* m_world; b2Body* m_prev; @@ -452,16 +460,16 @@ private: b2JointEdge* m_jointList; b2ContactEdge* m_contactList; - float32 m_mass, m_invMass; + float m_mass, m_invMass; // Rotational inertia about the center of mass. - float32 m_I, m_invI; + float m_I, m_invI; - float32 m_linearDamping; - float32 m_angularDamping; - float32 m_gravityScale; + float m_linearDamping; + float m_angularDamping; + float m_gravityScale; - float32 m_sleepTime; + float m_sleepTime; void* m_userData; }; @@ -481,7 +489,7 @@ inline const b2Vec2& b2Body::GetPosition() const return m_xf.p; } -inline float32 b2Body::GetAngle() const +inline float b2Body::GetAngle() const { return m_sweep.a; } @@ -516,7 +524,7 @@ inline const b2Vec2& b2Body::GetLinearVelocity() const return m_linearVelocity; } -inline void b2Body::SetAngularVelocity(float32 w) +inline void b2Body::SetAngularVelocity(float w) { if (m_type == b2_staticBody) { @@ -531,17 +539,17 @@ inline void b2Body::SetAngularVelocity(float32 w) m_angularVelocity = w; } -inline float32 b2Body::GetAngularVelocity() const +inline float b2Body::GetAngularVelocity() const { return m_angularVelocity; } -inline float32 b2Body::GetMass() const +inline float b2Body::GetMass() const { return m_mass; } -inline float32 b2Body::GetInertia() const +inline float b2Body::GetInertia() const { return m_I + m_mass * b2Dot(m_sweep.localCenter, m_sweep.localCenter); } @@ -583,32 +591,32 @@ inline b2Vec2 b2Body::GetLinearVelocityFromLocalPoint(const b2Vec2& localPoint) return GetLinearVelocityFromWorldPoint(GetWorldPoint(localPoint)); } -inline float32 b2Body::GetLinearDamping() const +inline float b2Body::GetLinearDamping() const { return m_linearDamping; } -inline void b2Body::SetLinearDamping(float32 linearDamping) +inline void b2Body::SetLinearDamping(float linearDamping) { m_linearDamping = linearDamping; } -inline float32 b2Body::GetAngularDamping() const +inline float b2Body::GetAngularDamping() const { return m_angularDamping; } -inline void b2Body::SetAngularDamping(float32 angularDamping) +inline void b2Body::SetAngularDamping(float angularDamping) { m_angularDamping = angularDamping; } -inline float32 b2Body::GetGravityScale() const +inline float b2Body::GetGravityScale() const { return m_gravityScale; } -inline void b2Body::SetGravityScale(float32 scale) +inline void b2Body::SetGravityScale(float scale) { m_gravityScale = scale; } @@ -632,13 +640,15 @@ inline bool b2Body::IsBullet() const inline void b2Body::SetAwake(bool flag) { + if (m_type == b2_staticBody) + { + return; + } + if (flag) { - if ((m_flags & e_awakeFlag) == 0) - { - m_flags |= e_awakeFlag; - m_sleepTime = 0.0f; - } + m_flags |= e_awakeFlag; + m_sleepTime = 0.0f; } else { @@ -656,9 +666,9 @@ inline bool b2Body::IsAwake() const return (m_flags & e_awakeFlag) == e_awakeFlag; } -inline bool b2Body::IsActive() const +inline bool b2Body::IsEnabled() const { - return (m_flags & e_activeFlag) == e_activeFlag; + return (m_flags & e_enabledFlag) == e_enabledFlag; } inline bool b2Body::IsFixedRotation() const @@ -773,7 +783,7 @@ inline void b2Body::ApplyForceToCenter(const b2Vec2& force, bool wake) } } -inline void b2Body::ApplyTorque(float32 torque, bool wake) +inline void b2Body::ApplyTorque(float torque, bool wake) { if (m_type != b2_dynamicBody) { @@ -812,7 +822,26 @@ inline void b2Body::ApplyLinearImpulse(const b2Vec2& impulse, const b2Vec2& poin } } -inline void b2Body::ApplyAngularImpulse(float32 impulse, bool wake) +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(float impulse, bool wake) { if (m_type != b2_dynamicBody) { @@ -837,7 +866,7 @@ inline void b2Body::SynchronizeTransform() m_xf.p = m_sweep.c - b2Mul(m_xf.q, m_sweep.localCenter); } -inline void b2Body::Advance(float32 alpha) +inline void b2Body::Advance(float alpha) { // Advance to the new safe time. This doesn't sync the broad-phase. m_sweep.Advance(alpha); diff --git a/src/libraries/Box2D/Collision/b2BroadPhase.h b/src/libraries/Box2D/b2_broad_phase.h similarity index 72% rename from src/libraries/Box2D/Collision/b2BroadPhase.h rename to src/libraries/Box2D/b2_broad_phase.h index 0c460cabb..cf1cf6773 100644 --- a/src/libraries/Box2D/Collision/b2BroadPhase.h +++ b/src/libraries/Box2D/b2_broad_phase.h @@ -1,28 +1,31 @@ -/* -* 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. -*/ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_BROAD_PHASE_H #define B2_BROAD_PHASE_H -#include -#include -#include -#include +#include "b2_settings.h" +#include "b2_collision.h" +#include "b2_dynamic_tree.h" struct b2Pair { @@ -62,7 +65,7 @@ public: /// Get the fat AABB for a proxy. const b2AABB& GetFatAABB(int32 proxyId) const; - /// Get user data from a proxy. Returns NULL if the id is invalid. + /// Get user data from a proxy. Returns nullptr if the id is invalid. void* GetUserData(int32 proxyId) const; /// Test overlap of fat AABBs. @@ -97,7 +100,7 @@ public: int32 GetTreeBalance() const; /// Get the quality metric of the embedded tree. - float32 GetTreeQuality() const; + float GetTreeQuality() const; /// Shift the world origin. Useful for large worlds. /// The shift formula is: position -= newOrigin @@ -128,22 +131,6 @@ private: 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); @@ -176,7 +163,7 @@ inline int32 b2BroadPhase::GetTreeBalance() const return m_tree.GetMaxBalance(); } -inline float32 b2BroadPhase::GetTreeQuality() const +inline float b2BroadPhase::GetTreeQuality() const { return m_tree.GetAreaRatio(); } @@ -204,37 +191,30 @@ void b2BroadPhase::UpdatePairs(T* callback) 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) + // Send pairs to caller + for (int32 i = 0; i < m_pairCount; ++i) { 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); + // Clear move flags + for (int32 i = 0; i < m_moveCount; ++i) + { + int32 proxyId = m_moveBuffer[i]; + if (proxyId == e_nullProxy) + { + continue; + } + + m_tree.ClearMoved(proxyId); + } + + // Reset move buffer + m_moveCount = 0; } template diff --git a/src/libraries/Box2D/b2_chain_shape.h b/src/libraries/Box2D/b2_chain_shape.h new file mode 100644 index 000000000..9ba0b8b1c --- /dev/null +++ b/src/libraries/Box2D/b2_chain_shape.h @@ -0,0 +1,100 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_CHAIN_SHAPE_H +#define B2_CHAIN_SHAPE_H + +#include "b2_shape.h" + +class b2EdgeShape; + +/// A chain shape is a free form sequence of line segments. +/// The chain has one-sided collision, with the surface normal pointing to the right of the edge. +/// This provides a counter-clockwise winding like the polygon shape. +/// 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 ghost vertices to connect multiple chains together. + /// @param vertices an array of vertices, these are copied + /// @param count the vertex count + /// @param prevVertex previous vertex from chain that connects to the start + /// @param nextVertex next vertex from chain that connects to the end + void CreateChain(const b2Vec2* vertices, int32 count, + const b2Vec2& prevVertex, 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, float density) const override; + + /// The vertices. Owned by this class. + b2Vec2* m_vertices; + + /// The vertex count. + int32 m_count; + + b2Vec2 m_prevVertex, m_nextVertex; +}; + +inline b2ChainShape::b2ChainShape() +{ + m_type = e_chain; + m_radius = b2_polygonRadius; + m_vertices = nullptr; + m_count = 0; +} + +#endif diff --git a/src/libraries/Box2D/b2_circle_shape.h b/src/libraries/Box2D/b2_circle_shape.h new file mode 100644 index 000000000..009d77db5 --- /dev/null +++ b/src/libraries/Box2D/b2_circle_shape.h @@ -0,0 +1,66 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_CIRCLE_SHAPE_H +#define B2_CIRCLE_SHAPE_H + +#include "b2_shape.h" + +/// A solid 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. + /// @note because the circle is solid, rays that start inside do not hit because the normal is + /// not defined. + 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, float 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/libraries/Box2D/Collision/b2Collision.h b/src/libraries/Box2D/b2_collision.h similarity index 81% rename from src/libraries/Box2D/Collision/b2Collision.h rename to src/libraries/Box2D/b2_collision.h index ad023b3ca..aaa207b35 100644 --- a/src/libraries/Box2D/Collision/b2Collision.h +++ b/src/libraries/Box2D/b2_collision.h @@ -1,25 +1,29 @@ -/* -* 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. -*/ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_COLLISION_H #define B2_COLLISION_H -#include +#include "b2_math.h" #include /// @file @@ -69,8 +73,8 @@ union b2ContactID struct b2ManifoldPoint { b2Vec2 localPoint; ///< usage depends on manifold type - float32 normalImpulse; ///< the non-penetration impulse - float32 tangentImpulse; ///< the friction impulse + float normalImpulse; ///< the non-penetration impulse + float tangentImpulse; ///< the friction impulse b2ContactID id; ///< uniquely identifies a contact point between two shapes }; @@ -114,12 +118,12 @@ struct b2WorldManifold /// 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); + const b2Transform& xfA, float radiusA, + const b2Transform& xfB, float 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 + float separations[b2_maxManifoldPoints]; ///< a negative value indicates overlap, in meters }; /// This is used for determining the state of contact points. @@ -147,7 +151,7 @@ struct b2ClipVertex struct b2RayCastInput { b2Vec2 p1, p2; - float32 maxFraction; + float maxFraction; }; /// Ray-cast output data. The ray hits at p1 + fraction * (p2 - p1), where p1 and p2 @@ -155,7 +159,7 @@ struct b2RayCastInput struct b2RayCastOutput { b2Vec2 normal; - float32 fraction; + float fraction; }; /// An axis aligned bounding box. @@ -177,10 +181,10 @@ struct b2AABB } /// Get the perimeter length - float32 GetPerimeter() const + float GetPerimeter() const { - float32 wx = upperBound.x - lowerBound.x; - float32 wy = upperBound.y - lowerBound.y; + float wx = upperBound.x - lowerBound.x; + float wy = upperBound.y - lowerBound.y; return 2.0f * (wx + wy); } @@ -235,14 +239,14 @@ 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. +/// Compute the collision manifold between an edge and a polygon. 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); + const b2Vec2& normal, float offset, int32 vertexIndexA); /// Determine if two generic shapes overlap. bool b2TestOverlap( const b2Shape* shapeA, int32 indexA, diff --git a/src/libraries/Box2D/Dynamics/Contacts/b2Contact.h b/src/libraries/Box2D/b2_contact.h similarity index 78% rename from src/libraries/Box2D/Dynamics/Contacts/b2Contact.h rename to src/libraries/Box2D/b2_contact.h index 36e31e256..d4c59c620 100644 --- a/src/libraries/Box2D/Dynamics/Contacts/b2Contact.h +++ b/src/libraries/Box2D/b2_contact.h @@ -1,28 +1,32 @@ -/* -* 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. -*/ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_CONTACT_H #define B2_CONTACT_H -#include -#include -#include -#include +#include "b2_collision.h" +#include "b2_fixture.h" +#include "b2_math.h" +#include "b2_shape.h" class b2Body; class b2Contact; @@ -32,16 +36,16 @@ class b2BlockAllocator; class b2StackAllocator; class b2ContactListener; -/// Friction mixing law. The idea is to allow either fixture to drive the restitution to zero. +/// 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) +inline float b2MixFriction(float friction1, float 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) +inline float b2MixRestitution(float restitution1, float restitution2) { return restitution1 > restitution2 ? restitution1 : restitution2; } @@ -117,29 +121,29 @@ public: /// Override the default friction mixture. You can call this in b2ContactListener::PreSolve. /// This value persists until set or reset. - void SetFriction(float32 friction); + void SetFriction(float friction); /// Get the friction. - float32 GetFriction() const; + float 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); + void SetRestitution(float restitution); /// Get the restitution. - float32 GetRestitution() const; + float 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); + void SetTangentSpeed(float speed); /// Get the desired tangent speed. In meters per second. - float32 GetTangentSpeed() const; + float GetTangentSpeed() const; /// Evaluate this contact with your own manifold and transforms. virtual void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) = 0; @@ -157,7 +161,7 @@ protected: // Used when crawling contact graph when forming islands. e_islandFlag = 0x0001, - // Set when the shapes are touching. + // Set when the shapes are touching. e_touchingFlag = 0x0002, // This contact can be disabled (by user) @@ -183,7 +187,7 @@ protected: static void Destroy(b2Contact* contact, b2Shape::Type typeA, b2Shape::Type typeB, b2BlockAllocator* allocator); static void Destroy(b2Contact* contact, b2BlockAllocator* allocator); - b2Contact() : m_fixtureA(NULL), m_fixtureB(NULL) {} + b2Contact() : m_fixtureA(nullptr), m_fixtureB(nullptr) {} b2Contact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB); virtual ~b2Contact() {} @@ -211,12 +215,12 @@ protected: b2Manifold m_manifold; int32 m_toiCount; - float32 m_toi; + float m_toi; - float32 m_friction; - float32 m_restitution; + float m_friction; + float m_restitution; - float32 m_tangentSpeed; + float m_tangentSpeed; }; inline b2Manifold* b2Contact::GetManifold() @@ -306,12 +310,12 @@ inline void b2Contact::FlagForFiltering() m_flags |= e_filterFlag; } -inline void b2Contact::SetFriction(float32 friction) +inline void b2Contact::SetFriction(float friction) { m_friction = friction; } -inline float32 b2Contact::GetFriction() const +inline float b2Contact::GetFriction() const { return m_friction; } @@ -321,12 +325,12 @@ inline void b2Contact::ResetFriction() m_friction = b2MixFriction(m_fixtureA->m_friction, m_fixtureB->m_friction); } -inline void b2Contact::SetRestitution(float32 restitution) +inline void b2Contact::SetRestitution(float restitution) { m_restitution = restitution; } -inline float32 b2Contact::GetRestitution() const +inline float b2Contact::GetRestitution() const { return m_restitution; } @@ -336,12 +340,12 @@ inline void b2Contact::ResetRestitution() m_restitution = b2MixRestitution(m_fixtureA->m_restitution, m_fixtureB->m_restitution); } -inline void b2Contact::SetTangentSpeed(float32 speed) +inline void b2Contact::SetTangentSpeed(float speed) { m_tangentSpeed = speed; } -inline float32 b2Contact::GetTangentSpeed() const +inline float b2Contact::GetTangentSpeed() const { return m_tangentSpeed; } diff --git a/src/libraries/Box2D/b2_contact_manager.h b/src/libraries/Box2D/b2_contact_manager.h new file mode 100644 index 000000000..efa156847 --- /dev/null +++ b/src/libraries/Box2D/b2_contact_manager.h @@ -0,0 +1,56 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_CONTACT_MANAGER_H +#define B2_CONTACT_MANAGER_H + +#include "b2_broad_phase.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/libraries/Box2D/Collision/b2Distance.h b/src/libraries/Box2D/b2_distance.h similarity index 52% rename from src/libraries/Box2D/Collision/b2Distance.h rename to src/libraries/Box2D/b2_distance.h index 7bae689d1..3fcefc413 100644 --- a/src/libraries/Box2D/Collision/b2Distance.h +++ b/src/libraries/Box2D/b2_distance.h @@ -1,26 +1,29 @@ +// MIT License -/* -* 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. -*/ +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_DISTANCE_H #define B2_DISTANCE_H -#include +#include "b2_math.h" class b2Shape; @@ -28,12 +31,16 @@ class b2Shape; /// It encapsulates any shape. struct b2DistanceProxy { - b2DistanceProxy() : m_vertices(NULL), m_count(0), m_radius(0.0f) {} + 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, float radius); + /// Get the supporting vertex index in the given direction. int32 GetSupport(const b2Vec2& d) const; @@ -49,14 +56,14 @@ struct b2DistanceProxy b2Vec2 m_buffer[2]; const b2Vec2* m_vertices; int32 m_count; - float32 m_radius; + float m_radius; }; /// Used to warm start b2Distance. /// Set count to zero on first call. struct b2SimplexCache { - float32 metric; ///< length or area + float metric; ///< length or area uint16 count; uint8 indexA[3]; ///< vertices on shape A uint8 indexB[3]; ///< vertices on shape B @@ -79,7 +86,7 @@ struct b2DistanceOutput { b2Vec2 pointA; ///< closest point on shapeA b2Vec2 pointB; ///< closest point on shapeB - float32 distance; + float distance; int32 iterations; ///< number of GJK iterations used }; @@ -90,6 +97,28 @@ 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; + float lambda; + int32 iterations; +}; + +/// Perform a linear shape cast of shape B moving and shape A fixed. Determines the hit point, normal, and translation fraction. +/// @returns true if hit, false if there is no hit or an initial overlap +bool b2ShapeCast(b2ShapeCastOutput* output, const b2ShapeCastInput* input); ////////////////////////////////////////////////////////////////////////// @@ -107,10 +136,10 @@ inline const b2Vec2& b2DistanceProxy::GetVertex(int32 index) const inline int32 b2DistanceProxy::GetSupport(const b2Vec2& d) const { int32 bestIndex = 0; - float32 bestValue = b2Dot(m_vertices[0], d); + float bestValue = b2Dot(m_vertices[0], d); for (int32 i = 1; i < m_count; ++i) { - float32 value = b2Dot(m_vertices[i], d); + float value = b2Dot(m_vertices[i], d); if (value > bestValue) { bestIndex = i; @@ -124,10 +153,10 @@ inline int32 b2DistanceProxy::GetSupport(const b2Vec2& d) const inline const b2Vec2& b2DistanceProxy::GetSupportVertex(const b2Vec2& d) const { int32 bestIndex = 0; - float32 bestValue = b2Dot(m_vertices[0], d); + float bestValue = b2Dot(m_vertices[0], d); for (int32 i = 1; i < m_count; ++i) { - float32 value = b2Dot(m_vertices[i], d); + float value = b2Dot(m_vertices[i], d); if (value > bestValue) { bestIndex = i; diff --git a/src/libraries/Box2D/b2_distance_joint.h b/src/libraries/Box2D/b2_distance_joint.h new file mode 100644 index 000000000..b339e9239 --- /dev/null +++ b/src/libraries/Box2D/b2_distance_joint.h @@ -0,0 +1,140 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_DISTANCE_JOINT_H +#define B2_DISTANCE_JOINT_H + +#include "b2_joint.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; + stiffness = 0.0f; + damping = 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. + float length; + + /// The linear stiffness in N/m. A value of 0 disables softness. + float stiffness; + + /// The linear damping in N*s/m. + float damping; +}; + +/// 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(float 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. + float GetReactionTorque(float 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(float length) { m_length = length; } + float GetLength() const { return m_length; } + + /// Set/get the linear stiffness in N/m + void SetStiffness(float stiffness) { m_stiffness = stiffness; } + float GetStiffness() const { return m_stiffness; } + + /// Set/get linear damping in N*s/m + void SetDamping(float damping) { m_damping = damping; } + float GetDamping() const { return m_damping; } + + /// 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; + + float m_stiffness; + float m_damping; + float m_bias; + + // Solver shared + b2Vec2 m_localAnchorA; + b2Vec2 m_localAnchorB; + float m_gamma; + float m_impulse; + float 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; + float m_invMassA; + float m_invMassB; + float m_invIA; + float m_invIB; + float m_mass; +}; + +#endif diff --git a/src/libraries/Box2D/b2_draw.h b/src/libraries/Box2D/b2_draw.h new file mode 100644 index 000000000..10cbf866f --- /dev/null +++ b/src/libraries/Box2D/b2_draw.h @@ -0,0 +1,101 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_DRAW_H +#define B2_DRAW_H + +#include "b2_math.h" + +/// Color for debug drawing. Each value has the range [0,1]. +struct b2Color +{ + b2Color() {} + b2Color(float rIn, float gIn, float bIn, float aIn = 1.0f) + { + r = rIn; g = gIn; b = bIn; a = aIn; + } + + void Set(float rIn, float gIn, float bIn, float aIn = 1.0f) + { + r = rIn; g = gIn; b = bIn; a = aIn; + } + + float 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, float radius, const b2Color& color) = 0; + + /// Draw a solid circle. + virtual void DrawSolidCircle(const b2Vec2& center, float 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, float size, const b2Color& color) = 0; + +protected: + uint32 m_drawFlags; +}; + +#endif diff --git a/src/libraries/Box2D/Collision/b2DynamicTree.h b/src/libraries/Box2D/b2_dynamic_tree.h similarity index 78% rename from src/libraries/Box2D/Collision/b2DynamicTree.h rename to src/libraries/Box2D/b2_dynamic_tree.h index bf80f73a1..b3ddb97ca 100644 --- a/src/libraries/Box2D/Collision/b2DynamicTree.h +++ b/src/libraries/Box2D/b2_dynamic_tree.h @@ -1,26 +1,30 @@ -/* -* 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. -*/ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_DYNAMIC_TREE_H #define B2_DYNAMIC_TREE_H -#include -#include +#include "b2_collision.h" +#include "b2_growable_stack.h" #define b2_nullNode (-1) @@ -48,6 +52,8 @@ struct b2TreeNode // leaf = 0, free node = -1 int32 height; + + bool moved; }; /// A dynamic AABB tree broad-phase, inspired by Nathanael Presson's btDbvt. @@ -83,6 +89,9 @@ public: /// @return the proxy user data or 0 if the id is invalid. void* GetUserData(int32 proxyId) const; + bool WasMoved(int32 proxyId) const; + void ClearMoved(int32 proxyId); + /// Get the fat AABB for a proxy. const b2AABB& GetFatAABB(int32 proxyId) const; @@ -113,7 +122,7 @@ public: int32 GetMaxBalance() const; /// Get the ratio of the sum of the node areas to the root area. - float32 GetAreaRatio() const; + float GetAreaRatio() const; /// Build an optimal tree. Very expensive. For testing. void RebuildBottomUp(); @@ -159,6 +168,18 @@ inline void* b2DynamicTree::GetUserData(int32 proxyId) const return m_nodes[proxyId].userData; } +inline bool b2DynamicTree::WasMoved(int32 proxyId) const +{ + b2Assert(0 <= proxyId && proxyId < m_nodeCapacity); + return m_nodes[proxyId].moved; +} + +inline void b2DynamicTree::ClearMoved(int32 proxyId) +{ + b2Assert(0 <= proxyId && proxyId < m_nodeCapacity); + m_nodes[proxyId].moved = false; +} + inline const b2AABB& b2DynamicTree::GetFatAABB(int32 proxyId) const { b2Assert(0 <= proxyId && proxyId < m_nodeCapacity); @@ -216,7 +237,7 @@ inline void b2DynamicTree::RayCast(T* callback, const b2RayCastInput& input) con // Separating axis for segment (Gino, p80). // |dot(v, p1 - c)| > dot(|v|, h) - float32 maxFraction = input.maxFraction; + float maxFraction = input.maxFraction; // Build a bounding box for the segment. b2AABB segmentAABB; @@ -248,7 +269,7 @@ inline void b2DynamicTree::RayCast(T* callback, const b2RayCastInput& input) con // |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); + float separation = b2Abs(b2Dot(v, p1 - c)) - b2Dot(abs_v, h); if (separation > 0.0f) { continue; @@ -261,7 +282,7 @@ inline void b2DynamicTree::RayCast(T* callback, const b2RayCastInput& input) con subInput.p2 = input.p2; subInput.maxFraction = maxFraction; - float32 value = callback->RayCastCallback(subInput, nodeId); + float value = callback->RayCastCallback(subInput, nodeId); if (value == 0.0f) { diff --git a/src/libraries/Box2D/b2_edge_shape.h b/src/libraries/Box2D/b2_edge_shape.h new file mode 100644 index 000000000..ed79b43e2 --- /dev/null +++ b/src/libraries/Box2D/b2_edge_shape.h @@ -0,0 +1,85 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_EDGE_SHAPE_H +#define B2_EDGE_SHAPE_H + +#include "b2_shape.h" + +/// A line segment (edge) shape. These can be connected in chains or loops +/// to other edge shapes. Edges created independently are two-sided and do +/// no provide smooth movement across junctions. +class b2EdgeShape : public b2Shape +{ +public: + b2EdgeShape(); + + /// Set this as a part of a sequence. Vertex v0 precedes the edge and vertex v3 + /// follows. These extra vertices are used to provide smooth movement + /// across junctions. This also makes the collision one-sided. The edge + /// normal points to the right looking from v1 to v2. + void SetOneSided(const b2Vec2& v0, const b2Vec2& v1,const b2Vec2& v2, const b2Vec2& v3); + + /// Set this as an isolated edge. Collision is two-sided. + void SetTwoSided(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, float 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; + + /// Uses m_vertex0 and m_vertex3 to create smooth collision. + bool m_oneSided; +}; + +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_oneSided = false; +} + +#endif diff --git a/src/libraries/Box2D/Dynamics/b2Fixture.h b/src/libraries/Box2D/b2_fixture.h similarity index 79% rename from src/libraries/Box2D/Dynamics/b2Fixture.h rename to src/libraries/Box2D/b2_fixture.h index 753127fbc..4cdde74d8 100644 --- a/src/libraries/Box2D/Dynamics/b2Fixture.h +++ b/src/libraries/Box2D/b2_fixture.h @@ -1,27 +1,31 @@ -/* -* 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. -*/ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_FIXTURE_H #define B2_FIXTURE_H -#include -#include -#include +#include "b2_body.h" +#include "b2_collision.h" +#include "b2_shape.h" class b2BlockAllocator; class b2Body; @@ -58,8 +62,8 @@ struct b2FixtureDef /// The constructor sets the default fixture definition values. b2FixtureDef() { - shape = NULL; - userData = NULL; + shape = nullptr; + userData = nullptr; friction = 0.2f; restitution = 0.0f; density = 0.0f; @@ -74,13 +78,13 @@ struct b2FixtureDef void* userData; /// The friction coefficient, usually in the range [0,1]. - float32 friction; + float friction; /// The restitution (elasticity) usually in the range [0,1]. - float32 restitution; + float restitution; /// The density, usually in kg/m^2. - float32 density; + float density; /// A sensor shape collects contact information but never generates a collision /// response. @@ -135,7 +139,7 @@ public: /// 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 NULL if the fixture is not attached. + /// 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; @@ -159,6 +163,7 @@ public: /// Cast a ray against this shape. /// @param output the ray-cast results. /// @param input the ray-cast input parameters. + /// @param childIndex the child shape index (e.g. edge index) 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 @@ -168,24 +173,24 @@ public: /// 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); + void SetDensity(float density); /// Get the density of this fixture. - float32 GetDensity() const; + float GetDensity() const; /// Get the coefficient of friction. - float32 GetFriction() const; + float GetFriction() const; /// Set the coefficient of friction. This will _not_ change the friction of /// existing contacts. - void SetFriction(float32 friction); + void SetFriction(float friction); /// Get the coefficient of restitution. - float32 GetRestitution() const; + float GetRestitution() const; /// Set the coefficient of restitution. This will _not_ change the restitution of /// existing contacts. - void SetRestitution(float32 restitution); + void SetRestitution(float 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 @@ -215,15 +220,15 @@ protected: void Synchronize(b2BroadPhase* broadPhase, const b2Transform& xf1, const b2Transform& xf2); - float32 m_density; + float m_density; b2Fixture* m_next; b2Body* m_body; b2Shape* m_shape; - float32 m_friction; - float32 m_restitution; + float m_friction; + float m_restitution; b2FixtureProxy* m_proxies; int32 m_proxyCount; @@ -290,33 +295,33 @@ inline const b2Fixture* b2Fixture::GetNext() const return m_next; } -inline void b2Fixture::SetDensity(float32 density) +inline void b2Fixture::SetDensity(float density) { b2Assert(b2IsValid(density) && density >= 0.0f); m_density = density; } -inline float32 b2Fixture::GetDensity() const +inline float b2Fixture::GetDensity() const { return m_density; } -inline float32 b2Fixture::GetFriction() const +inline float b2Fixture::GetFriction() const { return m_friction; } -inline void b2Fixture::SetFriction(float32 friction) +inline void b2Fixture::SetFriction(float friction) { m_friction = friction; } -inline float32 b2Fixture::GetRestitution() const +inline float b2Fixture::GetRestitution() const { return m_restitution; } -inline void b2Fixture::SetRestitution(float32 restitution) +inline void b2Fixture::SetRestitution(float restitution) { m_restitution = restitution; } diff --git a/src/libraries/Box2D/b2_friction_joint.h b/src/libraries/Box2D/b2_friction_joint.h new file mode 100644 index 000000000..d7b88245e --- /dev/null +++ b/src/libraries/Box2D/b2_friction_joint.h @@ -0,0 +1,123 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_FRICTION_JOINT_H +#define B2_FRICTION_JOINT_H + +#include "b2_joint.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. + float maxForce; + + /// The maximum friction torque in N-m. + float 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(float inv_dt) const override; + float GetReactionTorque(float 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(float force); + + /// Get the maximum friction force in N. + float GetMaxForce() const; + + /// Set the maximum friction torque in N*m. + void SetMaxTorque(float torque); + + /// Get the maximum friction torque in N*m. + float 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; + float m_angularImpulse; + float m_maxForce; + float m_maxTorque; + + // Solver temp + int32 m_indexA; + int32 m_indexB; + b2Vec2 m_rA; + b2Vec2 m_rB; + b2Vec2 m_localCenterA; + b2Vec2 m_localCenterB; + float m_invMassA; + float m_invMassB; + float m_invIA; + float m_invIB; + b2Mat22 m_linearMass; + float m_angularMass; +}; + +#endif diff --git a/src/libraries/Box2D/b2_gear_joint.h b/src/libraries/Box2D/b2_gear_joint.h new file mode 100644 index 000000000..69e67a199 --- /dev/null +++ b/src/libraries/Box2D/b2_gear_joint.h @@ -0,0 +1,129 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_GEAR_JOINT_H +#define B2_GEAR_JOINT_H + +#include "b2_joint.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. + float 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(float inv_dt) const override; + float GetReactionTorque(float 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(float ratio); + float 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; + + float m_referenceAngleA; + float m_referenceAngleB; + + float m_constant; + float m_ratio; + + float m_impulse; + + // Solver temp + int32 m_indexA, m_indexB, m_indexC, m_indexD; + b2Vec2 m_lcA, m_lcB, m_lcC, m_lcD; + float m_mA, m_mB, m_mC, m_mD; + float m_iA, m_iB, m_iC, m_iD; + b2Vec2 m_JvAC, m_JvBD; + float m_JwA, m_JwB, m_JwC, m_JwD; + float m_mass; +}; + +#endif diff --git a/src/libraries/Box2D/b2_growable_stack.h b/src/libraries/Box2D/b2_growable_stack.h new file mode 100644 index 000000000..a24984f0c --- /dev/null +++ b/src/libraries/Box2D/b2_growable_stack.h @@ -0,0 +1,90 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_GROWABLE_STACK_H +#define B2_GROWABLE_STACK_H + +#include "b2_settings.h" +#include + +/// 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 +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/libraries/Box2D/Dynamics/Joints/b2Joint.h b/src/libraries/Box2D/b2_joint.h similarity index 66% rename from src/libraries/Box2D/Dynamics/Joints/b2Joint.h rename to src/libraries/Box2D/b2_joint.h index dd076b6b2..c33ec90af 100644 --- a/src/libraries/Box2D/Dynamics/Joints/b2Joint.h +++ b/src/libraries/Box2D/b2_joint.h @@ -1,27 +1,32 @@ -/* -* 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. -*/ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_JOINT_H #define B2_JOINT_H -#include +#include "b2_math.h" class b2Body; +class b2Draw; class b2Joint; struct b2SolverData; class b2BlockAllocator; @@ -42,19 +47,11 @@ enum b2JointType e_motorJoint }; -enum b2LimitState -{ - e_inactiveLimit, - e_atLowerLimit, - e_atUpperLimit, - e_equalLimits -}; - struct b2Jacobian { b2Vec2 linear; - float32 angularA; - float32 angularB; + float angularA; + float angularB; }; /// A joint edge is used to connect bodies and joints together @@ -76,9 +73,9 @@ struct b2JointDef b2JointDef() { type = e_unknownJoint; - userData = NULL; - bodyA = NULL; - bodyB = NULL; + userData = nullptr; + bodyA = nullptr; + bodyB = nullptr; collideConnected = false; } @@ -98,6 +95,16 @@ struct b2JointDef bool collideConnected; }; +/// Utility to compute linear stiffness values from frequency and damping ratio +void b2LinearStiffness(float& stiffness, float& damping, + float frequencyHertz, float dampingRatio, + const b2Body* bodyA, const b2Body* bodyB); + +/// Utility to compute rotational stiffness values frequency and damping ratio +void b2AngularStiffness(float& stiffness, float& damping, + float frequencyHertz, float dampingRatio, + const b2Body* bodyA, const b2Body* bodyB); + /// The base joint class. Joints are used to constraint two bodies together in /// various fashions. Some joints also feature limits and motors. class b2Joint @@ -120,10 +127,10 @@ public: 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; + virtual b2Vec2 GetReactionForce(float inv_dt) const = 0; /// Get the reaction torque on bodyB in N*m. - virtual float32 GetReactionTorque(float32 inv_dt) const = 0; + virtual float GetReactionTorque(float inv_dt) const = 0; /// Get the next joint the world joint list. b2Joint* GetNext(); @@ -135,8 +142,8 @@ public: /// Set the user data pointer. void SetUserData(void* data); - /// Short-cut function to determine if either body is inactive. - bool IsActive() const; + /// Short-cut function to determine if either body is enabled. + bool IsEnabled() const; /// Get collide connected. /// Note: modifying the collide connect flag won't work correctly because @@ -144,11 +151,14 @@ public: bool GetCollideConnected() const; /// Dump this joint to the log file. - virtual void Dump() { b2Log("// Dump is not supported for this joint type.\n"); } + virtual void Dump() { b2Dump("// 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); } + /// Debug draw this joint + virtual void Draw(b2Draw* draw) const; + protected: friend class b2World; friend class b2Body; diff --git a/src/libraries/Box2D/Common/b2Math.h b/src/libraries/Box2D/b2_math.h similarity index 78% rename from src/libraries/Box2D/Common/b2Math.h rename to src/libraries/Box2D/b2_math.h index 755c519b0..afe421ba8 100644 --- a/src/libraries/Box2D/Common/b2Math.h +++ b/src/libraries/Box2D/b2_math.h @@ -1,49 +1,35 @@ -/* -* 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. -*/ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_MATH_H #define B2_MATH_H -#include +#include "b2_settings.h" #include /// This function is used to ensure that a floating point number is not a NaN or infinity. -inline bool b2IsValid(float32 x) +inline bool b2IsValid(float x) { - int32 ix = *reinterpret_cast(&x); - return (ix & 0x7f800000) != 0x7f800000; -} - -/// This is a approximate yet fast inverse square-root. -inline float32 b2InvSqrt(float32 x) -{ - union - { - float32 x; - int32 i; - } convert; - - convert.x = x; - float32 xhalf = 0.5f * x; - convert.i = 0x5f3759df - (convert.i >> 1); - x = convert.x; - x = x * (1.5f - xhalf * x * x); - return x; + return isfinite(x); } #define b2Sqrt(x) sqrtf(x) @@ -56,25 +42,25 @@ struct b2Vec2 b2Vec2() {} /// Construct using coordinates. - b2Vec2(float32 x, float32 y) : x(x), y(y) {} + b2Vec2(float xIn, float 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_; } + void Set(float x_, float 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 + float operator () (int32 i) const { return (&x)[i]; } /// Write to an indexed element. - float32& operator () (int32 i) + float& operator () (int32 i) { return (&x)[i]; } @@ -92,33 +78,33 @@ struct b2Vec2 } /// Multiply this vector by a scalar. - void operator *= (float32 a) + void operator *= (float a) { x *= a; y *= a; } /// Get the length of this vector (the norm). - float32 Length() const + float 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 + float LengthSquared() const { return x * x + y * y; } /// Convert this vector into a unit vector. Returns the length. - float32 Normalize() + float Normalize() { - float32 length = Length(); + float length = Length(); if (length < b2_epsilon) { return 0.0f; } - float32 invLength = 1.0f / length; + float invLength = 1.0f / length; x *= invLength; y *= invLength; @@ -137,7 +123,7 @@ struct b2Vec2 return b2Vec2(-y, x); } - float32 x, y; + float x, y; }; /// A 2D column vector with 3 elements. @@ -147,13 +133,13 @@ struct b2Vec3 b2Vec3() {} /// Construct using coordinates. - b2Vec3(float32 x, float32 y, float32 z) : x(x), y(y), z(z) {} + b2Vec3(float xIn, float yIn, float 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_; } + void Set(float x_, float y_, float z_) { x = x_; y = y_; z = z_; } /// Negate this vector. b2Vec3 operator -() const { b2Vec3 v; v.Set(-x, -y, -z); return v; } @@ -171,12 +157,12 @@ struct b2Vec3 } /// Multiply this vector by a scalar. - void operator *= (float32 s) + void operator *= (float s) { x *= s; y *= s; z *= s; } - float32 x, y, z; + float x, y, z; }; /// A 2-by-2 matrix. Stored in column-major order. @@ -193,7 +179,7 @@ struct b2Mat22 } /// Construct this matrix using scalars. - b2Mat22(float32 a11, float32 a12, float32 a21, float32 a22) + b2Mat22(float a11, float a12, float a21, float a22) { ex.x = a11; ex.y = a21; ey.x = a12; ey.y = a22; @@ -222,9 +208,9 @@ struct b2Mat22 b2Mat22 GetInverse() const { - float32 a = ex.x, b = ey.x, c = ex.y, d = ey.y; + float a = ex.x, b = ey.x, c = ex.y, d = ey.y; b2Mat22 B; - float32 det = a * d - b * c; + float det = a * d - b * c; if (det != 0.0f) { det = 1.0f / det; @@ -238,8 +224,8 @@ struct b2Mat22 /// 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; + float a11 = ex.x, a12 = ey.x, a21 = ex.y, a22 = ey.y; + float det = a11 * a22 - a12 * a21; if (det != 0.0f) { det = 1.0f / det; @@ -301,7 +287,7 @@ struct b2Rot b2Rot() {} /// Initialize from an angle in radians - explicit b2Rot(float32 angle) + explicit b2Rot(float angle) { /// TODO_ERIN optimize s = sinf(angle); @@ -309,7 +295,7 @@ struct b2Rot } /// Set using an angle in radians. - void Set(float32 angle) + void Set(float angle) { /// TODO_ERIN optimize s = sinf(angle); @@ -324,7 +310,7 @@ struct b2Rot } /// Get the angle in radians - float32 GetAngle() const + float GetAngle() const { return b2Atan2(s, c); } @@ -342,7 +328,7 @@ struct b2Rot } /// Sine and cosine - float32 s, c; + float s, c; }; /// A transform contains translation and rotation. It is used to represent @@ -363,7 +349,7 @@ struct b2Transform } /// Set this based on the position and angle. - void Set(const b2Vec2& position, float32 angle) + void Set(const b2Vec2& position, float angle) { p = position; q.Set(angle); @@ -380,50 +366,51 @@ struct b2Transform struct b2Sweep { /// Get the interpolated transform at a specific time. + /// @param transform the output transform /// @param beta is a factor in [0,1], where 0 indicates alpha0. - void GetTransform(b2Transform* xfb, float32 beta) const; + void GetTransform(b2Transform* transform, float beta) const; /// Advance the sweep forward, yielding a new initial state. /// @param alpha the new initial time. - void Advance(float32 alpha); + void Advance(float alpha); /// Normalize the angles. void Normalize(); b2Vec2 localCenter; ///< local center of mass position b2Vec2 c0, c; ///< center world positions - float32 a0, a; ///< world angles + float 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; + float alpha0; }; /// Useful constant extern const b2Vec2 b2Vec2_zero; /// Perform the dot product on two vectors. -inline float32 b2Dot(const b2Vec2& a, const b2Vec2& b) +inline float 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) +inline float 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) +inline b2Vec2 b2Cross(const b2Vec2& a, float 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) +inline b2Vec2 b2Cross(float s, const b2Vec2& a) { return b2Vec2(-s * a.y, s * a.x); } @@ -454,7 +441,7 @@ 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) +inline b2Vec2 operator * (float s, const b2Vec2& a) { return b2Vec2(s * a.x, s * a.y); } @@ -464,19 +451,24 @@ 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) +inline bool operator != (const b2Vec2& a, const b2Vec2& b) +{ + return a.x != b.x || a.y != b.y; +} + +inline float b2Distance(const b2Vec2& a, const b2Vec2& b) { b2Vec2 c = a - b; return c.Length(); } -inline float32 b2DistanceSquared(const b2Vec2& a, const b2Vec2& b) +inline float b2DistanceSquared(const b2Vec2& a, const b2Vec2& b) { b2Vec2 c = a - b; return b2Dot(c, c); } -inline b2Vec3 operator * (float32 s, const b2Vec3& a) +inline b2Vec3 operator * (float s, const b2Vec3& a) { return b2Vec3(s * a.x, s * a.y, s * a.z); } @@ -494,7 +486,7 @@ inline b2Vec3 operator - (const b2Vec3& a, const b2Vec3& b) } /// Perform the dot product on two vectors. -inline float32 b2Dot(const b2Vec3& a, const b2Vec3& b) +inline float b2Dot(const b2Vec3& a, const b2Vec3& b) { return a.x * b.x + a.y * b.y + a.z * b.z; } @@ -576,18 +568,18 @@ inline b2Vec2 b2MulT(const b2Rot& q, const b2Vec2& v) 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; + float x = (T.q.c * v.x - T.q.s * v.y) + T.p.x; + float 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); + float px = v.x - T.p.x; + float py = v.y - T.p.y; + float x = (T.q.c * px + T.q.s * py); + float y = (-T.q.s * px + T.q.c * py); return b2Vec2(x, y); } @@ -689,20 +681,20 @@ inline bool b2IsPowerOfTwo(uint32 x) return result; } -inline void b2Sweep::GetTransform(b2Transform* xf, float32 beta) const +inline void b2Sweep::GetTransform(b2Transform* xf, float beta) const { - xf->p = (1.0f - beta) * c0 + beta * c; - float32 angle = (1.0f - beta) * a0 + beta * a; + xf->p = c0 + beta * (c - c0); + float angle = a0 + beta * (a - a0); xf->q.Set(angle); // Shift to origin xf->p -= b2Mul(xf->q, localCenter); } -inline void b2Sweep::Advance(float32 alpha) +inline void b2Sweep::Advance(float alpha) { b2Assert(alpha0 < 1.0f); - float32 beta = (alpha - alpha0) / (1.0f - alpha0); + float beta = (alpha - alpha0) / (1.0f - alpha0); c0 += beta * (c - c0); a0 += beta * (a - a0); alpha0 = alpha; @@ -711,8 +703,8 @@ inline void b2Sweep::Advance(float32 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); + float twoPi = 2.0f * b2_pi; + float d = twoPi * floorf(a0 / twoPi); a0 -= d; a -= d; } diff --git a/src/libraries/Box2D/b2_motor_joint.h b/src/libraries/Box2D/b2_motor_joint.h new file mode 100644 index 000000000..c3f1adcbb --- /dev/null +++ b/src/libraries/Box2D/b2_motor_joint.h @@ -0,0 +1,137 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_MOTOR_JOINT_H +#define B2_MOTOR_JOINT_H + +#include "b2_joint.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. + float angularOffset; + + /// The maximum motor force in N. + float maxForce; + + /// The maximum motor torque in N-m. + float maxTorque; + + /// Position correction factor in the range [0,1]. + float 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(float inv_dt) const override; + float GetReactionTorque(float 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(float angularOffset); + float GetAngularOffset() const; + + /// Set the maximum friction force in N. + void SetMaxForce(float force); + + /// Get the maximum friction force in N. + float GetMaxForce() const; + + /// Set the maximum friction torque in N*m. + void SetMaxTorque(float torque); + + /// Get the maximum friction torque in N*m. + float GetMaxTorque() const; + + /// Set the position correction factor in the range [0,1]. + void SetCorrectionFactor(float factor); + + /// Get the position correction factor in the range [0,1]. + float 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; + float m_angularOffset; + b2Vec2 m_linearImpulse; + float m_angularImpulse; + float m_maxForce; + float m_maxTorque; + float 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; + float m_angularError; + float m_invMassA; + float m_invMassB; + float m_invIA; + float m_invIB; + b2Mat22 m_linearMass; + float m_angularMass; +}; + +#endif diff --git a/src/libraries/Box2D/b2_mouse_joint.h b/src/libraries/Box2D/b2_mouse_joint.h new file mode 100644 index 000000000..ebaa02592 --- /dev/null +++ b/src/libraries/Box2D/b2_mouse_joint.h @@ -0,0 +1,133 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_MOUSE_JOINT_H +#define B2_MOUSE_JOINT_H + +#include "b2_joint.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; + stiffness = 0.0f; + damping = 0.0f; + } + + /// 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). + float maxForce; + + /// The linear stiffness in N/m + float stiffness; + + /// The linear damping in N*s/m + float damping; +}; + +/// 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(float inv_dt) const override; + + /// Implements b2Joint. + float GetReactionTorque(float 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(float force); + float GetMaxForce() const; + + /// Set/get the linear stiffness in N/m + void SetStiffness(float stiffness) { m_stiffness = stiffness; } + float GetStiffness() const { return m_stiffness; } + + /// Set/get linear damping in N*s/m + void SetDamping(float damping) { m_damping = damping; } + float GetDamping() const { return m_damping; } + + /// 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; + float m_stiffness; + float m_damping; + float m_beta; + + // Solver shared + b2Vec2 m_impulse; + float m_maxForce; + float m_gamma; + + // Solver temp + int32 m_indexA; + int32 m_indexB; + b2Vec2 m_rB; + b2Vec2 m_localCenterB; + float m_invMassB; + float m_invIB; + b2Mat22 m_mass; + b2Vec2 m_C; +}; + +#endif diff --git a/src/libraries/Box2D/Collision/Shapes/b2PolygonShape.h b/src/libraries/Box2D/b2_polygon_shape.h similarity index 51% rename from src/libraries/Box2D/Collision/Shapes/b2PolygonShape.h rename to src/libraries/Box2D/b2_polygon_shape.h index b19298038..52f4cc0ec 100644 --- a/src/libraries/Box2D/Collision/Shapes/b2PolygonShape.h +++ b/src/libraries/Box2D/b2_polygon_shape.h @@ -1,27 +1,30 @@ -/* -* 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. -*/ +// MIT License +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_POLYGON_SHAPE_H #define B2_POLYGON_SHAPE_H -#include +#include "b2_shape.h" -/// A convex polygon. It is assumed that the interior of the polygon is to +/// A solid 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. @@ -31,10 +34,10 @@ public: b2PolygonShape(); /// Implement b2Shape. - b2Shape* Clone(b2BlockAllocator* allocator) const; + b2Shape* Clone(b2BlockAllocator* allocator) const override; /// @see b2Shape::GetChildCount - int32 GetChildCount() const; + 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]. @@ -46,33 +49,29 @@ public: /// 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); + void SetAsBox(float hx, float 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); + void SetAsBox(float hx, float hy, const b2Vec2& center, float angle); /// @see b2Shape::TestPoint - bool TestPoint(const b2Transform& transform, const b2Vec2& p) const; + bool TestPoint(const b2Transform& transform, const b2Vec2& p) const override; /// Implement b2Shape. + /// @note because the polygon is solid, rays that start inside do not hit because the normal is + /// not defined. bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, - const b2Transform& transform, int32 childIndex) const; + const b2Transform& transform, int32 childIndex) const override; /// @see b2Shape::ComputeAABB - void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const; + void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const override; /// @see b2Shape::ComputeMass - void ComputeMass(b2MassData* massData, float32 density) const; - - /// Get the vertex count. - int32 GetVertexCount() const { return m_count; } - - /// Get a vertex by index. - const b2Vec2& GetVertex(int32 index) const; + void ComputeMass(b2MassData* massData, float density) const override; /// Validate convexity. This is a very time consuming operation. /// @returns true if valid @@ -92,10 +91,4 @@ inline b2PolygonShape::b2PolygonShape() m_centroid.SetZero(); } -inline const b2Vec2& b2PolygonShape::GetVertex(int32 index) const -{ - b2Assert(0 <= index && index < m_count); - return m_vertices[index]; -} - #endif diff --git a/src/libraries/Box2D/Dynamics/Joints/b2PrismaticJoint.h b/src/libraries/Box2D/b2_prismatic_joint.h similarity index 58% rename from src/libraries/Box2D/Dynamics/Joints/b2PrismaticJoint.h rename to src/libraries/Box2D/b2_prismatic_joint.h index 6ef5d3ec0..09cbad540 100644 --- a/src/libraries/Box2D/Dynamics/Joints/b2PrismaticJoint.h +++ b/src/libraries/Box2D/b2_prismatic_joint.h @@ -1,25 +1,29 @@ -/* -* 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. -*/ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_PRISMATIC_JOINT_H #define B2_PRISMATIC_JOINT_H -#include +#include "b2_joint.h" /// Prismatic joint definition. This requires defining a line of /// motion using an axis and an anchor point. The definition uses local @@ -58,25 +62,25 @@ struct b2PrismaticJointDef : public b2JointDef b2Vec2 localAxisA; /// The constrained angle between the bodies: bodyB_angle - bodyA_angle. - float32 referenceAngle; + float referenceAngle; /// Enable/disable the joint limit. bool enableLimit; /// The lower translation limit, usually in meters. - float32 lowerTranslation; + float lowerTranslation; /// The upper translation limit, usually in meters. - float32 upperTranslation; + float upperTranslation; /// Enable/disable the joint motor. bool enableMotor; /// The maximum motor torque, usually in N-m. - float32 maxMotorForce; + float maxMotorForce; /// The desired motor speed in radians per second. - float32 motorSpeed; + float motorSpeed; }; /// A prismatic joint. This joint provides one degree of freedom: translation @@ -86,11 +90,11 @@ struct b2PrismaticJointDef : public b2JointDef class b2PrismaticJoint : public b2Joint { public: - b2Vec2 GetAnchorA() const; - b2Vec2 GetAnchorB() const; + b2Vec2 GetAnchorA() const override; + b2Vec2 GetAnchorB() const override; - b2Vec2 GetReactionForce(float32 inv_dt) const; - float32 GetReactionTorque(float32 inv_dt) const; + b2Vec2 GetReactionForce(float inv_dt) const override; + float GetReactionTorque(float inv_dt) const override; /// The local anchor point relative to bodyA's origin. const b2Vec2& GetLocalAnchorA() const { return m_localAnchorA; } @@ -102,13 +106,13 @@ public: const b2Vec2& GetLocalAxisA() const { return m_localXAxisA; } /// Get the reference angle. - float32 GetReferenceAngle() const { return m_referenceAngle; } + float GetReferenceAngle() const { return m_referenceAngle; } /// Get the current joint translation, usually in meters. - float32 GetJointTranslation() const; + float GetJointTranslation() const; /// Get the current joint translation speed, usually in meters per second. - float32 GetJointSpeed() const; + float GetJointSpeed() const; /// Is the joint limit enabled? bool IsLimitEnabled() const; @@ -117,13 +121,13 @@ public: void EnableLimit(bool flag); /// Get the lower joint limit, usually in meters. - float32 GetLowerLimit() const; + float GetLowerLimit() const; /// Get the upper joint limit, usually in meters. - float32 GetUpperLimit() const; + float GetUpperLimit() const; /// Set the joint limits, usually in meters. - void SetLimits(float32 lower, float32 upper); + void SetLimits(float lower, float upper); /// Is the joint motor enabled? bool IsMotorEnabled() const; @@ -132,63 +136,67 @@ public: void EnableMotor(bool flag); /// Set the motor speed, usually in meters per second. - void SetMotorSpeed(float32 speed); + void SetMotorSpeed(float speed); /// Get the motor speed, usually in meters per second. - float32 GetMotorSpeed() const; + float GetMotorSpeed() const; /// Set the maximum motor force, usually in N. - void SetMaxMotorForce(float32 force); - float32 GetMaxMotorForce() const { return m_maxMotorForce; } + void SetMaxMotorForce(float force); + float GetMaxMotorForce() const { return m_maxMotorForce; } /// Get the current motor force given the inverse time step, usually in N. - float32 GetMotorForce(float32 inv_dt) const; + float GetMotorForce(float inv_dt) const; /// Dump to b2Log - void Dump(); + void Dump() override; + + /// + void Draw(b2Draw* draw) const override; protected: friend class b2Joint; friend class b2GearJoint; b2PrismaticJoint(const b2PrismaticJointDef* def); - void InitVelocityConstraints(const b2SolverData& data); - void SolveVelocityConstraints(const b2SolverData& data); - bool SolvePositionConstraints(const b2SolverData& 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; 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; + float m_referenceAngle; + b2Vec2 m_impulse; + float m_motorImpulse; + float m_lowerImpulse; + float m_upperImpulse; + float m_lowerTranslation; + float m_upperTranslation; + float m_maxMotorForce; + float 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; + float m_invMassA; + float m_invMassB; + float m_invIA; + float m_invIB; b2Vec2 m_axis, m_perp; - float32 m_s1, m_s2; - float32 m_a1, m_a2; - b2Mat33 m_K; - float32 m_motorMass; + float m_s1, m_s2; + float m_a1, m_a2; + b2Mat22 m_K; + float m_translation; + float m_axialMass; }; -inline float32 b2PrismaticJoint::GetMotorSpeed() const +inline float b2PrismaticJoint::GetMotorSpeed() const { return m_motorSpeed; } diff --git a/src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.h b/src/libraries/Box2D/b2_pulley_joint.h similarity index 56% rename from src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.h rename to src/libraries/Box2D/b2_pulley_joint.h index 44843e7b4..14f12c41f 100644 --- a/src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.h +++ b/src/libraries/Box2D/b2_pulley_joint.h @@ -1,27 +1,31 @@ -/* -* 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. -*/ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_PULLEY_JOINT_H #define B2_PULLEY_JOINT_H -#include +#include "b2_joint.h" -const float32 b2_minPulleyLength = 2.0f; +const float b2_minPulleyLength = 2.0f; /// Pulley joint definition. This requires two ground anchors, /// two dynamic body anchor points, and a pulley ratio. @@ -44,7 +48,7 @@ struct b2PulleyJointDef : public b2JointDef void Initialize(b2Body* bodyA, b2Body* bodyB, const b2Vec2& groundAnchorA, const b2Vec2& groundAnchorB, const b2Vec2& anchorA, const b2Vec2& anchorB, - float32 ratio); + float ratio); /// The first ground anchor in world coordinates. This point never moves. b2Vec2 groundAnchorA; @@ -59,13 +63,13 @@ struct b2PulleyJointDef : public b2JointDef b2Vec2 localAnchorB; /// The a reference length for the segment attached to bodyA. - float32 lengthA; + float lengthA; /// The a reference length for the segment attached to bodyB. - float32 lengthB; + float lengthB; /// The pulley ratio, used to simulate a block-and-tackle. - float32 ratio; + float ratio; }; /// The pulley joint is connected to two bodies and two fixed ground points. @@ -79,11 +83,11 @@ struct b2PulleyJointDef : public b2JointDef class b2PulleyJoint : public b2Joint { public: - b2Vec2 GetAnchorA() const; - b2Vec2 GetAnchorB() const; + b2Vec2 GetAnchorA() const override; + b2Vec2 GetAnchorB() const override; - b2Vec2 GetReactionForce(float32 inv_dt) const; - float32 GetReactionTorque(float32 inv_dt) const; + b2Vec2 GetReactionForce(float inv_dt) const override; + float GetReactionTorque(float inv_dt) const override; /// Get the first ground anchor. b2Vec2 GetGroundAnchorA() const; @@ -92,46 +96,46 @@ public: b2Vec2 GetGroundAnchorB() const; /// Get the current length of the segment attached to bodyA. - float32 GetLengthA() const; + float GetLengthA() const; /// Get the current length of the segment attached to bodyB. - float32 GetLengthB() const; + float GetLengthB() const; /// Get the pulley ratio. - float32 GetRatio() const; + float GetRatio() const; /// Get the current length of the segment attached to bodyA. - float32 GetCurrentLengthA() const; + float GetCurrentLengthA() const; /// Get the current length of the segment attached to bodyB. - float32 GetCurrentLengthB() const; + float GetCurrentLengthB() const; /// Dump joint to dmLog - void Dump(); + void Dump() override; /// Implement b2Joint::ShiftOrigin - void ShiftOrigin(const b2Vec2& newOrigin); + void ShiftOrigin(const b2Vec2& newOrigin) override; protected: friend class b2Joint; b2PulleyJoint(const b2PulleyJointDef* data); - void InitVelocityConstraints(const b2SolverData& data); - void SolveVelocityConstraints(const b2SolverData& data); - bool SolvePositionConstraints(const b2SolverData& 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; + float m_lengthA; + float m_lengthB; // Solver shared b2Vec2 m_localAnchorA; b2Vec2 m_localAnchorB; - float32 m_constant; - float32 m_ratio; - float32 m_impulse; + float m_constant; + float m_ratio; + float m_impulse; // Solver temp int32 m_indexA; @@ -142,11 +146,11 @@ protected: b2Vec2 m_rB; b2Vec2 m_localCenterA; b2Vec2 m_localCenterB; - float32 m_invMassA; - float32 m_invMassB; - float32 m_invIA; - float32 m_invIB; - float32 m_mass; + float m_invMassA; + float m_invMassB; + float m_invIA; + float m_invIB; + float m_mass; }; #endif diff --git a/src/libraries/Box2D/Dynamics/Joints/b2RevoluteJoint.h b/src/libraries/Box2D/b2_revolute_joint.h similarity index 55% rename from src/libraries/Box2D/Dynamics/Joints/b2RevoluteJoint.h rename to src/libraries/Box2D/b2_revolute_joint.h index bbed4a6cb..f202e3551 100644 --- a/src/libraries/Box2D/Dynamics/Joints/b2RevoluteJoint.h +++ b/src/libraries/Box2D/b2_revolute_joint.h @@ -1,32 +1,35 @@ -/* -* 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. -*/ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_REVOLUTE_JOINT_H #define B2_REVOLUTE_JOINT_H -#include +#include "b2_joint.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. +/// 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. @@ -59,26 +62,26 @@ struct b2RevoluteJointDef : public b2JointDef b2Vec2 localAnchorB; /// The bodyB angle minus bodyA angle in the reference state (radians). - float32 referenceAngle; + float referenceAngle; /// A flag to enable joint limits. bool enableLimit; /// The lower angle for the joint limit (radians). - float32 lowerAngle; + float lowerAngle; /// The upper angle for the joint limit (radians). - float32 upperAngle; + float upperAngle; /// A flag to enable the joint motor. bool enableMotor; /// The desired motor speed. Usually in radians per second. - float32 motorSpeed; + float motorSpeed; /// The maximum motor torque used to achieve the desired motor speed. /// Usually in N-m. - float32 maxMotorTorque; + float maxMotorTorque; }; /// A revolute joint constrains two bodies to share a common point while they @@ -90,8 +93,8 @@ struct b2RevoluteJointDef : public b2JointDef class b2RevoluteJoint : public b2Joint { public: - b2Vec2 GetAnchorA() const; - b2Vec2 GetAnchorB() const; + b2Vec2 GetAnchorA() const override; + b2Vec2 GetAnchorB() const override; /// The local anchor point relative to bodyA's origin. const b2Vec2& GetLocalAnchorA() const { return m_localAnchorA; } @@ -100,13 +103,13 @@ public: const b2Vec2& GetLocalAnchorB() const { return m_localAnchorB; } /// Get the reference angle. - float32 GetReferenceAngle() const { return m_referenceAngle; } + float GetReferenceAngle() const { return m_referenceAngle; } /// Get the current joint angle in radians. - float32 GetJointAngle() const; + float GetJointAngle() const; /// Get the current joint angle speed in radians per second. - float32 GetJointSpeed() const; + float GetJointSpeed() const; /// Is the joint limit enabled? bool IsLimitEnabled() const; @@ -115,13 +118,13 @@ public: void EnableLimit(bool flag); /// Get the lower joint limit in radians. - float32 GetLowerLimit() const; + float GetLowerLimit() const; /// Get the upper joint limit in radians. - float32 GetUpperLimit() const; + float GetUpperLimit() const; /// Set the joint limits in radians. - void SetLimits(float32 lower, float32 upper); + void SetLimits(float lower, float upper); /// Is the joint motor enabled? bool IsMotorEnabled() const; @@ -130,29 +133,32 @@ public: void EnableMotor(bool flag); /// Set the motor speed in radians per second. - void SetMotorSpeed(float32 speed); + void SetMotorSpeed(float speed); /// Get the motor speed in radians per second. - float32 GetMotorSpeed() const; + float GetMotorSpeed() const; /// Set the maximum motor torque, usually in N-m. - void SetMaxMotorTorque(float32 torque); - float32 GetMaxMotorTorque() const { return m_maxMotorTorque; } + void SetMaxMotorTorque(float torque); + float GetMaxMotorTorque() const { return m_maxMotorTorque; } /// Get the reaction force given the inverse time step. /// Unit is N. - b2Vec2 GetReactionForce(float32 inv_dt) const; + b2Vec2 GetReactionForce(float 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; + float GetReactionTorque(float inv_dt) const override; /// Get the current motor torque given the inverse time step. /// Unit is N*m. - float32 GetMotorTorque(float32 inv_dt) const; + float GetMotorTorque(float inv_dt) const; /// Dump to b2Log. - void Dump(); + void Dump() override; + + /// + void Draw(b2Draw* draw) const override; protected: @@ -161,24 +167,24 @@ protected: b2RevoluteJoint(const b2RevoluteJointDef* def); - void InitVelocityConstraints(const b2SolverData& data); - void SolveVelocityConstraints(const b2SolverData& data); - bool SolvePositionConstraints(const b2SolverData& 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; - b2Vec3 m_impulse; - float32 m_motorImpulse; - + b2Vec2 m_impulse; + float m_motorImpulse; + float m_lowerImpulse; + float m_upperImpulse; bool m_enableMotor; - float32 m_maxMotorTorque; - float32 m_motorSpeed; - + float m_maxMotorTorque; + float m_motorSpeed; bool m_enableLimit; - float32 m_referenceAngle; - float32 m_lowerAngle; - float32 m_upperAngle; + float m_referenceAngle; + float m_lowerAngle; + float m_upperAngle; // Solver temp int32 m_indexA; @@ -187,16 +193,16 @@ protected: 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; + float m_invMassA; + float m_invMassB; + float m_invIA; + float m_invIB; + b2Mat22 m_K; + float m_angle; + float m_axialMass; }; -inline float32 b2RevoluteJoint::GetMotorSpeed() const +inline float b2RevoluteJoint::GetMotorSpeed() const { return m_motorSpeed; } diff --git a/src/libraries/Box2D/b2_rope.h b/src/libraries/Box2D/b2_rope.h new file mode 100644 index 000000000..5f1cc4073 --- /dev/null +++ b/src/libraries/Box2D/b2_rope.h @@ -0,0 +1,150 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_ROPE_H +#define B2_ROPE_H + +#include "b2_math.h" + +class b2Draw; +struct b2RopeStretch; +struct b2RopeBend; + +enum b2StretchingModel +{ + b2_pbdStretchingModel, + b2_xpbdStretchingModel +}; + +enum b2BendingModel +{ + b2_springAngleBendingModel = 0, + b2_pbdAngleBendingModel, + b2_xpbdAngleBendingModel, + b2_pbdDistanceBendingModel, + b2_pbdHeightBendingModel +}; + +/// +struct b2RopeTuning +{ + b2RopeTuning() + { + stretchingModel = b2_pbdStretchingModel; + bendingModel = b2_pbdAngleBendingModel; + damping = 0.0f; + stretchStiffness = 1.0f; + bendStiffness = 0.5f; + bendHertz = 1.0f; + bendDamping = 0.0f; + isometric = false; + fixedEffectiveMass = false; + warmStart = false; + } + + b2StretchingModel stretchingModel; + b2BendingModel bendingModel; + float damping; + float stretchStiffness; + float stretchHertz; + float stretchDamping; + float bendStiffness; + float bendHertz; + float bendDamping; + bool isometric; + bool fixedEffectiveMass; + bool warmStart; +}; + +/// +struct b2RopeDef +{ + b2RopeDef() + { + position.SetZero(); + vertices = nullptr; + count = 0; + masses = nullptr; + gravity.SetZero(); + } + + b2Vec2 position; + b2Vec2* vertices; + int32 count; + float* masses; + b2Vec2 gravity; + b2RopeTuning tuning; +}; + +/// +class b2Rope +{ +public: + b2Rope(); + ~b2Rope(); + + /// + void Create(const b2RopeDef& def); + + /// + void SetTuning(const b2RopeTuning& tuning); + + /// + void Step(float timeStep, int32 iterations, const b2Vec2& position); + + /// + void Reset(const b2Vec2& position); + + /// + void Draw(b2Draw* draw) const; + +private: + + void SolveStretch_PBD(); + void SolveStretch_XPBD(float dt); + void SolveBend_PBD_Angle(); + void SolveBend_XPBD_Angle(float dt); + void SolveBend_PBD_Distance(); + void SolveBend_PBD_Height(); + void ApplyBendForces(float dt); + + b2Vec2 m_position; + + int32 m_count; + int32 m_stretchCount; + int32 m_bendCount; + + b2RopeStretch* m_stretchConstraints; + b2RopeBend* m_bendConstraints; + + b2Vec2* m_bindPositions; + b2Vec2* m_ps; + b2Vec2* m_p0s; + b2Vec2* m_vs; + + float* m_invMasses; + b2Vec2 m_gravity; + + b2RopeTuning m_tuning; +}; + +#endif diff --git a/src/libraries/Box2D/b2_rope_joint.h b/src/libraries/Box2D/b2_rope_joint.h new file mode 100644 index 000000000..b254b3a22 --- /dev/null +++ b/src/libraries/Box2D/b2_rope_joint.h @@ -0,0 +1,118 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_ROPE_JOINT_H +#define B2_ROPE_JOINT_H + +#include "b2_joint.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. + float 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(float inv_dt) const override; + float GetReactionTorque(float 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(float length) { m_maxLength = length; } + float GetMaxLength() const; + + // Get current length + float GetLength() 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; + float m_maxLength; + float m_length; + float 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; + float m_invMassA; + float m_invMassB; + float m_invIA; + float m_invIB; + float m_mass; +}; + +#endif diff --git a/src/libraries/Box2D/Common/b2Settings.h b/src/libraries/Box2D/b2_settings.h similarity index 74% rename from src/libraries/Box2D/Common/b2Settings.h rename to src/libraries/Box2D/b2_settings.h index beaa1d47b..3b17e12fb 100644 --- a/src/libraries/Box2D/Common/b2Settings.h +++ b/src/libraries/Box2D/b2_settings.h @@ -1,20 +1,24 @@ -/* -* 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. -*/ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_SETTINGS_H #define B2_SETTINGS_H @@ -23,11 +27,12 @@ #include #include -void loveAssert(bool test, const char *teststr); +#if !defined(NDEBUG) + #define b2DEBUG +#endif #define B2_NOT_USED(x) ((void)(x)) -//#define b2Assert(A) assert(A) -#define b2Assert(A) loveAssert((A), #A) +#define b2Assert(A) assert(A) typedef signed char int8; typedef signed short int16; @@ -35,8 +40,6 @@ 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 @@ -64,7 +67,7 @@ typedef double float64; /// 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 +#define b2_aabbMultiplier 4.0f /// A small length used as a collision and constraint tolerance. Usually it is /// chosen to be numerically significant, but visually insignificant. @@ -114,7 +117,7 @@ typedef double float64; /// 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 +#define b2_toiBaumgarte 0.75f // Sleep @@ -139,6 +142,11 @@ void b2Free(void* mem); /// Logging function. void b2Log(const char* string, ...); +/// Dump to a file. Only one dump file allowed at a time. +void b2OpenDump(const char* fileName); +void b2Dump(const char* string, ...); +void b2CloseDump(); + /// Version numbering scheme. /// See http://en.wikipedia.org/wiki/Software_versioning struct b2Version diff --git a/src/libraries/Box2D/Collision/Shapes/b2Shape.h b/src/libraries/Box2D/b2_shape.h similarity index 62% rename from src/libraries/Box2D/Collision/Shapes/b2Shape.h rename to src/libraries/Box2D/b2_shape.h index 170ea1a13..27e3d14bc 100644 --- a/src/libraries/Box2D/Collision/Shapes/b2Shape.h +++ b/src/libraries/Box2D/b2_shape.h @@ -1,39 +1,44 @@ -/* -* 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. -*/ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_SHAPE_H #define B2_SHAPE_H -#include -#include -#include +#include "b2_math.h" +#include "b2_collision.h" + +class b2BlockAllocator; /// This holds the mass data computed for a shape. struct b2MassData { /// The mass of the shape, usually in kilograms. - float32 mass; + float 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; + float I; }; /// A shape is used for collision detection. You can create a shape however you like. @@ -87,10 +92,13 @@ public: /// 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; + virtual void ComputeMass(b2MassData* massData, float density) const = 0; Type m_type; - float32 m_radius; + + /// Radius of a shape. For polygonal shapes this must be b2_polygonRadius. There is no support for + /// making rounded polygons. + float m_radius; }; inline b2Shape::Type b2Shape::GetType() const diff --git a/src/libraries/Box2D/b2_stack_allocator.h b/src/libraries/Box2D/b2_stack_allocator.h new file mode 100644 index 000000000..780ab7945 --- /dev/null +++ b/src/libraries/Box2D/b2_stack_allocator.h @@ -0,0 +1,64 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_STACK_ALLOCATOR_H +#define B2_STACK_ALLOCATOR_H + +#include "b2_settings.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/libraries/Box2D/b2_time_of_impact.h b/src/libraries/Box2D/b2_time_of_impact.h new file mode 100644 index 000000000..bb3031fcb --- /dev/null +++ b/src/libraries/Box2D/b2_time_of_impact.h @@ -0,0 +1,62 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_TIME_OF_IMPACT_H +#define B2_TIME_OF_IMPACT_H + +#include "b2_math.h" +#include "b2_distance.h" + +/// Input parameters for b2TimeOfImpact +struct b2TOIInput +{ + b2DistanceProxy proxyA; + b2DistanceProxy proxyB; + b2Sweep sweepA; + b2Sweep sweepB; + float 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; + float 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/libraries/Box2D/b2_time_step.h b/src/libraries/Box2D/b2_time_step.h new file mode 100644 index 000000000..f0304a300 --- /dev/null +++ b/src/libraries/Box2D/b2_time_step.h @@ -0,0 +1,73 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_TIME_STEP_H +#define B2_TIME_STEP_H + +#include "b2_math.h" + +/// Profiling data. Times are in milliseconds. +struct b2Profile +{ + float step; + float collide; + float solve; + float solveInit; + float solveVelocity; + float solvePosition; + float broadphase; + float solveTOI; +}; + +/// This is an internal structure. +struct b2TimeStep +{ + float dt; // time step + float inv_dt; // inverse time step (0 if dt == 0). + float dtRatio; // dt * inv_dt0 + int32 velocityIterations; + int32 positionIterations; + bool warmStarting; +}; + +/// This is an internal structure. +struct b2Position +{ + b2Vec2 c; + float a; +}; + +/// This is an internal structure. +struct b2Velocity +{ + b2Vec2 v; + float w; +}; + +/// Solver Data +struct b2SolverData +{ + b2TimeStep step; + b2Position* positions; + b2Velocity* velocities; +}; + +#endif diff --git a/src/libraries/Box2D/b2_timer.h b/src/libraries/Box2D/b2_timer.h new file mode 100644 index 000000000..a664de833 --- /dev/null +++ b/src/libraries/Box2D/b2_timer.h @@ -0,0 +1,54 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_TIMER_H +#define B2_TIMER_H + +#include "b2_settings.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. + float GetMilliseconds() const; + +private: + +#if defined(_WIN32) + double m_start; + static double 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/libraries/Box2D/b2_weld_joint.h b/src/libraries/Box2D/b2_weld_joint.h new file mode 100644 index 000000000..fd5537f34 --- /dev/null +++ b/src/libraries/Box2D/b2_weld_joint.h @@ -0,0 +1,132 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_WELD_JOINT_H +#define B2_WELD_JOINT_H + +#include "b2_joint.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; + stiffness = 0.0f; + damping = 0.0f; + } + + /// Initialize the bodies, anchors, reference angle, stiffness, and damping. + /// @param bodyA the first body connected by this joint + /// @param bodyB the second body connected by this joint + /// @param anchor the point of connection in world coordinates + 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). + float referenceAngle; + + /// The rotational stiffness in N*m + /// Disable softness with a value of 0 + float stiffness; + + /// The rotational damping in N*m*s + float damping; +}; + +/// 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(float inv_dt) const override; + float GetReactionTorque(float 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. + float GetReferenceAngle() const { return m_referenceAngle; } + + /// Set/get stiffness in N*m + void SetStiffness(float hz) { m_stiffness = hz; } + float GetStiffness() const { return m_stiffness; } + + /// Set/get damping in N*m*s + void SetDamping(float damping) { m_damping = damping; } + float GetDamping() const { return m_damping; } + + /// 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; + + float m_stiffness; + float m_damping; + float m_bias; + + // Solver shared + b2Vec2 m_localAnchorA; + b2Vec2 m_localAnchorB; + float m_referenceAngle; + float 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; + float m_invMassA; + float m_invMassB; + float m_invIA; + float m_invIB; + b2Mat33 m_mass; +}; + +#endif diff --git a/src/libraries/Box2D/b2_wheel_joint.h b/src/libraries/Box2D/b2_wheel_joint.h new file mode 100644 index 000000000..1b8f43739 --- /dev/null +++ b/src/libraries/Box2D/b2_wheel_joint.h @@ -0,0 +1,239 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_WHEEL_JOINT_H +#define B2_WHEEL_JOINT_H + +#include "b2_joint.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); + enableLimit = false; + lowerTranslation = 0.0f; + upperTranslation = 0.0f; + enableMotor = false; + maxMotorTorque = 0.0f; + motorSpeed = 0.0f; + stiffness = 0.0f; + damping = 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, 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 limit. + bool enableLimit; + + /// The lower translation limit, usually in meters. + float lowerTranslation; + + /// The upper translation limit, usually in meters. + float upperTranslation; + + /// Enable/disable the joint motor. + bool enableMotor; + + /// The maximum motor torque, usually in N-m. + float maxMotorTorque; + + /// The desired motor speed in radians per second. + float motorSpeed; + + /// Suspension stiffness. Typically in units N/m. + float stiffness; + + /// Suspension damping. Typically in units of N*s/m. + float damping; +}; + +/// 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. The spring/damper is +/// initialized upon creation. This joint is designed for vehicle suspensions. +class b2WheelJoint : public b2Joint +{ +public: + b2Vec2 GetAnchorA() const override; + b2Vec2 GetAnchorB() const override; + + b2Vec2 GetReactionForce(float inv_dt) const override; + float GetReactionTorque(float 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. + float GetJointTranslation() const; + + /// Get the current joint linear speed, usually in meters per second. + float GetJointLinearSpeed() const; + + /// Get the current joint angle in radians. + float GetJointAngle() const; + + /// Get the current joint angular speed in radians per second. + float GetJointAngularSpeed() const; + + /// Is the joint limit enabled? + bool IsLimitEnabled() const; + + /// Enable/disable the joint translation limit. + void EnableLimit(bool flag); + + /// Get the lower joint translation limit, usually in meters. + float GetLowerLimit() const; + + /// Get the upper joint translation limit, usually in meters. + float GetUpperLimit() const; + + /// Set the joint translation limits, usually in meters. + void SetLimits(float lower, float upper); + + /// 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(float speed); + + /// Get the motor speed, usually in radians per second. + float GetMotorSpeed() const; + + /// Set/Get the maximum motor force, usually in N-m. + void SetMaxMotorTorque(float torque); + float GetMaxMotorTorque() const; + + /// Get the current motor torque given the inverse time step, usually in N-m. + float GetMotorTorque(float inv_dt) const; + + /// Access spring stiffness + void SetStiffness(float stiffness); + float GetStiffness() const; + + /// Access damping + void SetDamping(float damping); + float GetDamping() const; + + /// Dump to b2Log + void Dump() override; + + /// + void Draw(b2Draw* draw) const 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; + + b2Vec2 m_localAnchorA; + b2Vec2 m_localAnchorB; + b2Vec2 m_localXAxisA; + b2Vec2 m_localYAxisA; + + float m_impulse; + float m_motorImpulse; + float m_springImpulse; + + float m_lowerImpulse; + float m_upperImpulse; + float m_translation; + float m_lowerTranslation; + float m_upperTranslation; + + float m_maxMotorTorque; + float m_motorSpeed; + + bool m_enableLimit; + bool m_enableMotor; + + float m_stiffness; + float m_damping; + + // Solver temp + int32 m_indexA; + int32 m_indexB; + b2Vec2 m_localCenterA; + b2Vec2 m_localCenterB; + float m_invMassA; + float m_invMassB; + float m_invIA; + float m_invIB; + + b2Vec2 m_ax, m_ay; + float m_sAx, m_sBx; + float m_sAy, m_sBy; + + float m_mass; + float m_motorMass; + float m_axialMass; + float m_springMass; + + float m_bias; + float m_gamma; + +}; + +inline float b2WheelJoint::GetMotorSpeed() const +{ + return m_motorSpeed; +} + +inline float b2WheelJoint::GetMaxMotorTorque() const +{ + return m_maxMotorTorque; +} + +#endif diff --git a/src/libraries/Box2D/Dynamics/b2World.h b/src/libraries/Box2D/b2_world.h similarity index 82% rename from src/libraries/Box2D/Dynamics/b2World.h rename to src/libraries/Box2D/b2_world.h index 3968cc784..3ddc136e3 100644 --- a/src/libraries/Box2D/Dynamics/b2World.h +++ b/src/libraries/Box2D/b2_world.h @@ -1,30 +1,34 @@ -/* -* 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. -*/ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_WORLD_H #define B2_WORLD_H -#include -#include -#include -#include -#include -#include +#include "b2_block_allocator.h" +#include "b2_contact_manager.h" +#include "b2_math.h" +#include "b2_stack_allocator.h" +#include "b2_time_step.h" +#include "b2_world_callbacks.h" struct b2AABB; struct b2BodyDef; @@ -62,7 +66,7 @@ public: 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 + /// inside with b2World::DebugDraw method. The debug draw object is owned /// by you and must remain in scope. void SetDebugDraw(b2Draw* debugDraw); @@ -91,7 +95,7 @@ public: /// @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, + void Step( float timeStep, int32 velocityIterations, int32 positionIterations); @@ -105,7 +109,7 @@ public: void ClearForces(); /// Call this to draw shapes and other debug draw data. This is intentionally non-const. - void DrawDebugData(); + void DebugDraw(); /// Query the world for all fixtures that potentially overlap the /// provided AABB. @@ -122,19 +126,19 @@ public: 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 NULL body indicates the end of the list. + /// 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 NULL joint indicates the end of the list. + /// 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 NULL contact indicates the end of the list. + /// 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. @@ -177,7 +181,7 @@ public: /// Get the quality metric of the dynamic tree. The smaller the better. /// The minimum is 1. - float32 GetTreeQuality() const; + float GetTreeQuality() const; /// Change the global gravity vector. void SetGravity(const b2Vec2& gravity); @@ -211,14 +215,6 @@ public: private: - // m_flags - enum - { - e_newFixture = 0x0001, - e_locked = 0x0002, - e_clearForces = 0x0004 - }; - friend class b2Body; friend class b2Fixture; friend class b2ContactManager; @@ -227,14 +223,11 @@ private: 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; @@ -247,11 +240,15 @@ private: bool m_allowSleep; b2DestructionListener* m_destructionListener; - b2Draw* g_debugDraw; + b2Draw* m_debugDraw; // This is used to compute the time step ratio to // support a variable time step. - float32 m_inv_dt0; + float m_inv_dt0; + + bool m_newContacts; + bool m_locked; + bool m_clearForces; // These are for debugging the solver. bool m_warmStarting; @@ -320,25 +317,18 @@ inline b2Vec2 b2World::GetGravity() const inline bool b2World::IsLocked() const { - return (m_flags & e_locked) == e_locked; + return m_locked; } inline void b2World::SetAutoClearForces(bool flag) { - if (flag) - { - m_flags |= e_clearForces; - } - else - { - m_flags &= ~e_clearForces; - } + m_clearForces = flag; } /// 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; + return m_clearForces; } inline const b2ContactManager& b2World::GetContactManager() const diff --git a/src/libraries/Box2D/Dynamics/b2WorldCallbacks.h b/src/libraries/Box2D/b2_world_callbacks.h similarity index 76% rename from src/libraries/Box2D/Dynamics/b2WorldCallbacks.h rename to src/libraries/Box2D/b2_world_callbacks.h index 82ffc0229..e1e75c9e9 100644 --- a/src/libraries/Box2D/Dynamics/b2WorldCallbacks.h +++ b/src/libraries/Box2D/b2_world_callbacks.h @@ -1,25 +1,29 @@ -/* -* 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. -*/ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_WORLD_CALLBACKS_H #define B2_WORLD_CALLBACKS_H -#include +#include "b2_settings.h" struct b2Vec2; struct b2Transform; @@ -64,8 +68,8 @@ public: /// match up one-to-one with the contact points in b2Manifold. struct b2ContactImpulse { - float32 normalImpulses[b2_maxManifoldPoints]; - float32 tangentImpulses[b2_maxManifoldPoints]; + float normalImpulses[b2_maxManifoldPoints]; + float tangentImpulses[b2_maxManifoldPoints]; int32 count; }; @@ -146,10 +150,11 @@ public: /// @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 + /// @param fraction the fraction along the ray 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; + virtual float ReportFixture( b2Fixture* fixture, const b2Vec2& point, + const b2Vec2& normal, float fraction) = 0; }; #endif diff --git a/src/modules/physics/box2d/Body.cpp b/src/modules/physics/box2d/Body.cpp index 2f8301be0..05a287f8f 100644 --- a/src/modules/physics/box2d/Body.cpp +++ b/src/modules/physics/box2d/Body.cpp @@ -372,7 +372,7 @@ void Body::setBullet(bool bullet) bool Body::isActive() const { - return body->IsActive(); + return body->IsEnabled(); } bool Body::isAwake() const @@ -392,7 +392,7 @@ bool Body::isSleepingAllowed() const void Body::setActive(bool active) { - body->SetActive(active); + body->SetEnabled(active); } void Body::setAwake(bool awake) diff --git a/src/modules/physics/box2d/ChainShape.cpp b/src/modules/physics/box2d/ChainShape.cpp index 7b04c61a1..d0326d741 100644 --- a/src/modules/physics/box2d/ChainShape.cpp +++ b/src/modules/physics/box2d/ChainShape.cpp @@ -47,56 +47,44 @@ void ChainShape::setNextVertex(float x, float y) { b2Vec2 v(x, y); b2ChainShape *c = (b2ChainShape *)shape; - c->SetNextVertex(Physics::scaleDown(v)); + c->m_nextVertex = Physics::scaleDown(v); } void ChainShape::setNextVertex() { b2ChainShape *c = (b2ChainShape *)shape; - c->m_hasNextVertex = false; } void ChainShape::setPreviousVertex(float x, float y) { b2Vec2 v(x, y); b2ChainShape *c = (b2ChainShape *)shape; - c->SetPrevVertex(Physics::scaleDown(v)); + c->m_prevVertex = Physics::scaleDown(v); } void ChainShape::setPreviousVertex() { b2ChainShape *c = (b2ChainShape *)shape; - c->m_hasPrevVertex = false; } bool ChainShape::getNextVertex(float &x, float &y) const { b2ChainShape *c = (b2ChainShape *)shape; - if (c->m_hasNextVertex) - { - b2Vec2 v = Physics::scaleUp(c->m_nextVertex); - x = v.x; - y = v.y; - return true; - } - - return false; + b2Vec2 v = Physics::scaleUp(c->m_nextVertex); + x = v.x; + y = v.y; + return true; } bool ChainShape::getPreviousVertex(float &x, float &y) const { b2ChainShape *c = (b2ChainShape *)shape; - if (c->m_hasPrevVertex) - { - b2Vec2 v = Physics::scaleUp(c->m_prevVertex); - x = v.x; - y = v.y; - return true; - } - - return false; + b2Vec2 v = Physics::scaleUp(c->m_prevVertex); + x = v.x; + y = v.y; + return true; } EdgeShape *ChainShape::getChildEdge(int index) const diff --git a/src/modules/physics/box2d/DistanceJoint.cpp b/src/modules/physics/box2d/DistanceJoint.cpp index 3e7c27597..b1a67cd66 100644 --- a/src/modules/physics/box2d/DistanceJoint.cpp +++ b/src/modules/physics/box2d/DistanceJoint.cpp @@ -58,22 +58,22 @@ float DistanceJoint::getLength() const void DistanceJoint::setFrequency(float hz) { - joint->SetFrequency(hz); + joint->SetStiffness(hz); } float DistanceJoint::getFrequency() const { - return joint->GetFrequency(); + return joint->GetStiffness(); } void DistanceJoint::setDampingRatio(float d) { - joint->SetDampingRatio(d); + joint->SetDamping(d); } float DistanceJoint::getDampingRatio() const { - return joint->GetDampingRatio(); + return joint->GetDamping(); } diff --git a/src/modules/physics/box2d/EdgeShape.cpp b/src/modules/physics/box2d/EdgeShape.cpp index ebe1d0423..68cc4b09a 100644 --- a/src/modules/physics/box2d/EdgeShape.cpp +++ b/src/modules/physics/box2d/EdgeShape.cpp @@ -48,28 +48,21 @@ void EdgeShape::setNextVertex(float x, float y) b2EdgeShape *e = (b2EdgeShape *)shape; b2Vec2 v(x, y); e->m_vertex3 = Physics::scaleDown(v); - e->m_hasVertex3 = true; } void EdgeShape::setNextVertex() { b2EdgeShape *e = (b2EdgeShape *)shape; - e->m_hasVertex3 = false; } bool EdgeShape::getNextVertex(float &x, float &y) const { b2EdgeShape *e = (b2EdgeShape *)shape; - if (e->m_hasVertex3) - { - b2Vec2 v = Physics::scaleUp(e->m_vertex3); - x = v.x; - y = v.y; - return true; - } - - return false; + b2Vec2 v = Physics::scaleUp(e->m_vertex3); + x = v.x; + y = v.y; + return true; } void EdgeShape::setPreviousVertex(float x, float y) @@ -77,28 +70,21 @@ void EdgeShape::setPreviousVertex(float x, float y) b2EdgeShape *e = (b2EdgeShape *)shape; b2Vec2 v(x, y); e->m_vertex0 = Physics::scaleDown(v); - e->m_hasVertex0 = true; } void EdgeShape::setPreviousVertex() { b2EdgeShape *e = (b2EdgeShape *)shape; - e->m_hasVertex0 = false; } bool EdgeShape::getPreviousVertex(float &x, float &y) const { b2EdgeShape *e = (b2EdgeShape *)shape; - if (e->m_hasVertex0) - { - b2Vec2 v = Physics::scaleUp(e->m_vertex0); - x = v.x; - y = v.y; - return true; - } - - return false; + b2Vec2 v = Physics::scaleUp(e->m_vertex0); + x = v.x; + y = v.y; + return true; } int EdgeShape::getPoints(lua_State *L) diff --git a/src/modules/physics/box2d/Joint.cpp b/src/modules/physics/box2d/Joint.cpp index e73ee84d4..0cd08455d 100644 --- a/src/modules/physics/box2d/Joint.cpp +++ b/src/modules/physics/box2d/Joint.cpp @@ -187,7 +187,7 @@ void Joint::destroyJoint(bool implicit) bool Joint::isActive() const { - return joint->IsActive(); + return joint->IsEnabled(); } bool Joint::getCollideConnected() const diff --git a/src/modules/physics/box2d/MouseJoint.cpp b/src/modules/physics/box2d/MouseJoint.cpp index f9ae91745..814e507e2 100644 --- a/src/modules/physics/box2d/MouseJoint.cpp +++ b/src/modules/physics/box2d/MouseJoint.cpp @@ -86,22 +86,22 @@ void MouseJoint::setFrequency(float hz) if (hz <= FLT_EPSILON * 2) throw love::Exception("MouseJoint frequency must be a positive number."); - joint->SetFrequency(hz); + joint->SetStiffness(hz); } float MouseJoint::getFrequency() const { - return joint->GetFrequency(); + return joint->GetStiffness(); } void MouseJoint::setDampingRatio(float d) { - joint->SetDampingRatio(d); + joint->SetDamping(d); } float MouseJoint::getDampingRatio() const { - return joint->GetDampingRatio(); + return joint->GetDamping(); } Body *MouseJoint::getBodyA() const diff --git a/src/modules/physics/box2d/Physics.cpp b/src/modules/physics/box2d/Physics.cpp index 89fadd989..4bc447bc7 100644 --- a/src/modules/physics/box2d/Physics.cpp +++ b/src/modules/physics/box2d/Physics.cpp @@ -86,7 +86,7 @@ PolygonShape *Physics::newRectangleShape(float x, float y, float w, float h, flo EdgeShape *Physics::newEdgeShape(float x1, float y1, float x2, float y2) { b2EdgeShape *s = new b2EdgeShape(); - s->Set(Physics::scaleDown(b2Vec2(x1, y1)), Physics::scaleDown(b2Vec2(x2, y2))); + s->SetTwoSided(Physics::scaleDown(b2Vec2(x1, y1)), Physics::scaleDown(b2Vec2(x2, y2))); return new EdgeShape(s); } @@ -196,7 +196,7 @@ int Physics::newChainShape(lua_State *L) if (loop) s->CreateLoop(vecs, vcount); else - s->CreateChain(vecs, vcount); + s->CreateChain(vecs, vcount, vecs[0], vecs[vcount-1]); } catch (love::Exception &) { @@ -298,29 +298,7 @@ int Physics::getDistance(lua_State *L) { Fixture *fixtureA = luax_checktype(L, 1); Fixture *fixtureB = luax_checktype(L, 2); - b2DistanceProxy pA, pB; - b2DistanceInput i; - b2DistanceOutput o; - b2SimplexCache c; - c.count = 0; - - luax_catchexcept(L, [&]() { - pA.Set(fixtureA->fixture->GetShape(), 0); - pB.Set(fixtureB->fixture->GetShape(), 0); - i.proxyA = pA; - i.proxyB = pB; - i.transformA = fixtureA->fixture->GetBody()->GetTransform(); - i.transformB = fixtureB->fixture->GetBody()->GetTransform(); - i.useRadii = true; - b2Distance(&o, &c, &i); - }); - - lua_pushnumber(L, Physics::scaleUp(o.distance)); - lua_pushnumber(L, Physics::scaleUp(o.pointA.x)); - lua_pushnumber(L, Physics::scaleUp(o.pointA.y)); - lua_pushnumber(L, Physics::scaleUp(o.pointB.x)); - lua_pushnumber(L, Physics::scaleUp(o.pointB.y)); - return 5; + return 0; } void Physics::setMeter(float scale) diff --git a/src/modules/physics/box2d/PolygonShape.cpp b/src/modules/physics/box2d/PolygonShape.cpp index 436692ccc..b9b6e0c53 100644 --- a/src/modules/physics/box2d/PolygonShape.cpp +++ b/src/modules/physics/box2d/PolygonShape.cpp @@ -47,10 +47,10 @@ int PolygonShape::getPoints(lua_State *L) { love::luax_assert_argc(L, 0); b2PolygonShape *p = (b2PolygonShape *)shape; - int count = p->GetVertexCount(); + int count = p->m_count; for (int i = 0; iGetVertex(i)); + b2Vec2 v = Physics::scaleUp(p->m_vertices[i]); lua_pushnumber(L, v.x); lua_pushnumber(L, v.y); } diff --git a/src/modules/physics/box2d/WeldJoint.cpp b/src/modules/physics/box2d/WeldJoint.cpp index 9259ad46c..efdc6e948 100644 --- a/src/modules/physics/box2d/WeldJoint.cpp +++ b/src/modules/physics/box2d/WeldJoint.cpp @@ -68,22 +68,22 @@ void WeldJoint::init(b2WeldJointDef &def, Body *body1, Body *body2, float xA, fl void WeldJoint::setFrequency(float hz) { - joint->SetFrequency(hz); + joint->SetStiffness(hz); } float WeldJoint::getFrequency() const { - return joint->GetFrequency(); + return joint->GetStiffness(); } void WeldJoint::setDampingRatio(float d) { - joint->SetDampingRatio(d); + joint->SetDamping(d); } float WeldJoint::getDampingRatio() const { - return joint->GetDampingRatio(); + return joint->GetDamping(); } float WeldJoint::getReferenceAngle() const diff --git a/src/modules/physics/box2d/WheelJoint.cpp b/src/modules/physics/box2d/WheelJoint.cpp index 80fa529b9..1d3035ee9 100644 --- a/src/modules/physics/box2d/WheelJoint.cpp +++ b/src/modules/physics/box2d/WheelJoint.cpp @@ -57,7 +57,7 @@ float WheelJoint::getJointTranslation() const float WheelJoint::getJointSpeed() const { - return Physics::scaleUp(joint->GetJointSpeed()); + return Physics::scaleUp(joint->GetJointLinearSpeed()); } void WheelJoint::setMotorEnabled(bool enable) @@ -97,22 +97,22 @@ float WheelJoint::getMotorTorque(float inv_dt) const void WheelJoint::setSpringFrequency(float hz) { - joint->SetSpringFrequencyHz(hz); + joint->SetStiffness(hz); } float WheelJoint::getSpringFrequency() const { - return joint->GetSpringFrequencyHz(); + return joint->GetStiffness(); } void WheelJoint::setSpringDampingRatio(float ratio) { - joint->SetSpringDampingRatio(ratio); + joint->SetDamping(ratio); } float WheelJoint::getSpringDampingRatio() const { - return joint->GetSpringDampingRatio(); + return joint->GetDamping(); } int WheelJoint::getAxis(lua_State *L) diff --git a/src/modules/physics/box2d/World.cpp b/src/modules/physics/box2d/World.cpp index 2257f8443..aa05ff826 100644 --- a/src/modules/physics/box2d/World.cpp +++ b/src/modules/physics/box2d/World.cpp @@ -183,7 +183,7 @@ World::RayCastCallback::~RayCastCallback() { } -float32 World::RayCastCallback::ReportFixture(b2Fixture *fixture, const b2Vec2 &point, const b2Vec2 &normal, float32 fraction) +float World::RayCastCallback::ReportFixture(b2Fixture *fixture, const b2Vec2 &point, const b2Vec2 &normal, float fraction) { if (L != nullptr) { @@ -201,7 +201,7 @@ float32 World::RayCastCallback::ReportFixture(b2Fixture *fixture, const b2Vec2 & lua_call(L, 6, 1); if (!lua_isnumber(L, -1)) luaL_error(L, "Raycast callback didn't return a number!"); - float32 fraction = (float32) lua_tonumber(L, -1); + float fraction = (float) lua_tonumber(L, -1); lua_pop(L, 1); return fraction; } diff --git a/src/modules/physics/box2d/World.h b/src/modules/physics/box2d/World.h index 17102ee10..ea5ce3186 100644 --- a/src/modules/physics/box2d/World.h +++ b/src/modules/physics/box2d/World.h @@ -107,7 +107,7 @@ public: public: RayCastCallback(World *world, lua_State *L, int idx); ~RayCastCallback(); - virtual float32 ReportFixture(b2Fixture *fixture, const b2Vec2 &point, const b2Vec2 &normal, float32 fraction); + virtual float ReportFixture(b2Fixture *fixture, const b2Vec2 &point, const b2Vec2 &normal, float fraction); private: World *world; lua_State *L; From a5004f4c8d586385660b70c0e4bfd98dbccf04f3 Mon Sep 17 00:00:00 2001 From: Garrett Brown Date: Sun, 16 Aug 2020 18:25:03 -0400 Subject: [PATCH 02/57] Add assert modification --- src/libraries/Box2D/b2_settings.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libraries/Box2D/b2_settings.h b/src/libraries/Box2D/b2_settings.h index 3b17e12fb..8695980e1 100644 --- a/src/libraries/Box2D/b2_settings.h +++ b/src/libraries/Box2D/b2_settings.h @@ -27,12 +27,15 @@ #include #include +void loveAssert(bool test, const char* teststr); + #if !defined(NDEBUG) #define b2DEBUG #endif #define B2_NOT_USED(x) ((void)(x)) -#define b2Assert(A) assert(A) +//#define b2Assert(A) assert(A) +#define b2Assert(A) loveAssert((A), #A) typedef signed char int8; typedef signed short int16; From 59a1a4b2cd550618b0425d7f6f77c7c7978f3321 Mon Sep 17 00:00:00 2001 From: Garrett Brown Date: Sun, 16 Aug 2020 18:25:27 -0400 Subject: [PATCH 03/57] Finish wrapper function renames --- src/modules/physics/box2d/Body.cpp | 6 +++--- src/modules/physics/box2d/Body.h | 4 ++-- src/modules/physics/box2d/ChainShape.cpp | 16 ++-------------- src/modules/physics/box2d/ChainShape.h | 6 ++---- src/modules/physics/box2d/DistanceJoint.cpp | 8 ++++---- src/modules/physics/box2d/DistanceJoint.h | 8 ++++---- src/modules/physics/box2d/EdgeShape.cpp | 16 ++-------------- src/modules/physics/box2d/EdgeShape.h | 6 ++---- src/modules/physics/box2d/Joint.cpp | 2 +- src/modules/physics/box2d/Joint.h | 2 +- src/modules/physics/box2d/MouseJoint.cpp | 12 ++++++------ src/modules/physics/box2d/MouseJoint.h | 8 ++++---- src/modules/physics/box2d/WeldJoint.cpp | 8 ++++---- src/modules/physics/box2d/WeldJoint.h | 8 ++++---- src/modules/physics/box2d/WheelJoint.cpp | 8 ++++---- src/modules/physics/box2d/WheelJoint.h | 8 ++++---- 16 files changed, 49 insertions(+), 77 deletions(-) diff --git a/src/modules/physics/box2d/Body.cpp b/src/modules/physics/box2d/Body.cpp index 05a287f8f..abba1a202 100644 --- a/src/modules/physics/box2d/Body.cpp +++ b/src/modules/physics/box2d/Body.cpp @@ -370,7 +370,7 @@ void Body::setBullet(bool bullet) return body->SetBullet(bullet); } -bool Body::isActive() const +bool Body::isEnabled() const { return body->IsEnabled(); } @@ -390,9 +390,9 @@ bool Body::isSleepingAllowed() const return body->IsSleepingAllowed(); } -void Body::setActive(bool active) +void Body::SetEnabled(bool enabled) { - body->SetEnabled(active); + body->SetEnabled(enabled); } void Body::setAwake(bool awake) diff --git a/src/modules/physics/box2d/Body.h b/src/modules/physics/box2d/Body.h index 6c2edcc62..f5281c486 100644 --- a/src/modules/physics/box2d/Body.h +++ b/src/modules/physics/box2d/Body.h @@ -350,7 +350,7 @@ public: * Checks whether a Body is active or not. An inactive body * cannot be interacted with. **/ - bool isActive() const; + bool isEnabled() const; /** * Checks whether a Body is awake or not. A Body @@ -367,7 +367,7 @@ public: /** * Changes the body's active state. **/ - void setActive(bool active); + void SetEnabled(bool enabled); /** * Changes the body's sleep state. diff --git a/src/modules/physics/box2d/ChainShape.cpp b/src/modules/physics/box2d/ChainShape.cpp index d0326d741..0d2a83de6 100644 --- a/src/modules/physics/box2d/ChainShape.cpp +++ b/src/modules/physics/box2d/ChainShape.cpp @@ -50,11 +50,6 @@ void ChainShape::setNextVertex(float x, float y) c->m_nextVertex = Physics::scaleDown(v); } -void ChainShape::setNextVertex() -{ - b2ChainShape *c = (b2ChainShape *)shape; -} - void ChainShape::setPreviousVertex(float x, float y) { b2Vec2 v(x, y); @@ -62,29 +57,22 @@ void ChainShape::setPreviousVertex(float x, float y) c->m_prevVertex = Physics::scaleDown(v); } -void ChainShape::setPreviousVertex() -{ - b2ChainShape *c = (b2ChainShape *)shape; -} - -bool ChainShape::getNextVertex(float &x, float &y) const +void ChainShape::getNextVertex(float &x, float &y) const { b2ChainShape *c = (b2ChainShape *)shape; b2Vec2 v = Physics::scaleUp(c->m_nextVertex); x = v.x; y = v.y; - return true; } -bool ChainShape::getPreviousVertex(float &x, float &y) const +void ChainShape::getPreviousVertex(float &x, float &y) const { b2ChainShape *c = (b2ChainShape *)shape; b2Vec2 v = Physics::scaleUp(c->m_prevVertex); x = v.x; y = v.y; - return true; } EdgeShape *ChainShape::getChildEdge(int index) const diff --git a/src/modules/physics/box2d/ChainShape.h b/src/modules/physics/box2d/ChainShape.h index 06c192be1..67d7e7a7b 100644 --- a/src/modules/physics/box2d/ChainShape.h +++ b/src/modules/physics/box2d/ChainShape.h @@ -56,7 +56,6 @@ public: * @param y The y-coordinate of the vertex. **/ void setNextVertex(float x, float y); - void setNextVertex(); /** * Establish connectivity to a vertex that precedes @@ -65,17 +64,16 @@ public: * @param y The y-coordinate of the vertex. **/ void setPreviousVertex(float x, float y); - void setPreviousVertex(); /** * Gets the vertex that follows the last vertex. **/ - bool getNextVertex(float &x, float &y) const; + void getNextVertex(float &x, float &y) const; /** * Gets the vertex that precedes the first vertex. **/ - bool getPreviousVertex(float &x, float &y) const; + void getPreviousVertex(float &x, float &y) const; /** * Returns a child EdgeShape. diff --git a/src/modules/physics/box2d/DistanceJoint.cpp b/src/modules/physics/box2d/DistanceJoint.cpp index b1a67cd66..ffe80a8d6 100644 --- a/src/modules/physics/box2d/DistanceJoint.cpp +++ b/src/modules/physics/box2d/DistanceJoint.cpp @@ -56,22 +56,22 @@ float DistanceJoint::getLength() const return Physics::scaleUp(joint->GetLength()); } -void DistanceJoint::setFrequency(float hz) +void DistanceJoint::setStiffness(float hz) { joint->SetStiffness(hz); } -float DistanceJoint::getFrequency() const +float DistanceJoint::getStiffness() const { return joint->GetStiffness(); } -void DistanceJoint::setDampingRatio(float d) +void DistanceJoint::setDamping(float d) { joint->SetDamping(d); } -float DistanceJoint::getDampingRatio() const +float DistanceJoint::getDamping() const { return joint->GetDamping(); } diff --git a/src/modules/physics/box2d/DistanceJoint.h b/src/modules/physics/box2d/DistanceJoint.h index 10c61db18..3ca572525 100644 --- a/src/modules/physics/box2d/DistanceJoint.h +++ b/src/modules/physics/box2d/DistanceJoint.h @@ -59,24 +59,24 @@ public: /** * Sets the response speed. **/ - void setFrequency(float hz); + void setStiffness(float hz); /** * Gets the response speed. **/ - float getFrequency() const; + float getStiffness() const; /** * Sets the damping ratio. * 0 = no damping, 1 = critical damping. **/ - void setDampingRatio(float d); + void setDamping(float d); /** * Gets the damping ratio. * 0 = no damping, 1 = critical damping. **/ - float getDampingRatio() const; + float getDamping() const; private: // The Box2D DistanceJoint object. diff --git a/src/modules/physics/box2d/EdgeShape.cpp b/src/modules/physics/box2d/EdgeShape.cpp index 68cc4b09a..5810851e7 100644 --- a/src/modules/physics/box2d/EdgeShape.cpp +++ b/src/modules/physics/box2d/EdgeShape.cpp @@ -50,19 +50,13 @@ void EdgeShape::setNextVertex(float x, float y) e->m_vertex3 = Physics::scaleDown(v); } -void EdgeShape::setNextVertex() -{ - b2EdgeShape *e = (b2EdgeShape *)shape; -} - -bool EdgeShape::getNextVertex(float &x, float &y) const +void EdgeShape::getNextVertex(float &x, float &y) const { b2EdgeShape *e = (b2EdgeShape *)shape; b2Vec2 v = Physics::scaleUp(e->m_vertex3); x = v.x; y = v.y; - return true; } void EdgeShape::setPreviousVertex(float x, float y) @@ -72,19 +66,13 @@ void EdgeShape::setPreviousVertex(float x, float y) e->m_vertex0 = Physics::scaleDown(v); } -void EdgeShape::setPreviousVertex() -{ - b2EdgeShape *e = (b2EdgeShape *)shape; -} - -bool EdgeShape::getPreviousVertex(float &x, float &y) const +void EdgeShape::getPreviousVertex(float &x, float &y) const { b2EdgeShape *e = (b2EdgeShape *)shape; b2Vec2 v = Physics::scaleUp(e->m_vertex0); x = v.x; y = v.y; - return true; } int EdgeShape::getPoints(lua_State *L) diff --git a/src/modules/physics/box2d/EdgeShape.h b/src/modules/physics/box2d/EdgeShape.h index 0eb814eac..591606686 100644 --- a/src/modules/physics/box2d/EdgeShape.h +++ b/src/modules/physics/box2d/EdgeShape.h @@ -50,12 +50,10 @@ public: virtual ~EdgeShape(); void setNextVertex(float x, float y); - void setNextVertex(); - bool getNextVertex(float &x, float &y) const; + void getNextVertex(float &x, float &y) const; void setPreviousVertex(float x, float y); - void setPreviousVertex(); - bool getPreviousVertex(float &x, float &y) const; + void getPreviousVertex(float &x, float &y) const; /** * Returns the transformed points of the edge shape. diff --git a/src/modules/physics/box2d/Joint.cpp b/src/modules/physics/box2d/Joint.cpp index 0cd08455d..b1d8cccaa 100644 --- a/src/modules/physics/box2d/Joint.cpp +++ b/src/modules/physics/box2d/Joint.cpp @@ -185,7 +185,7 @@ void Joint::destroyJoint(bool implicit) this->release(); } -bool Joint::isActive() const +bool Joint::isEnabled() const { return joint->IsEnabled(); } diff --git a/src/modules/physics/box2d/Joint.h b/src/modules/physics/box2d/Joint.h index 094c54b2c..31ebdbe79 100644 --- a/src/modules/physics/box2d/Joint.h +++ b/src/modules/physics/box2d/Joint.h @@ -103,7 +103,7 @@ public: **/ float getReactionTorque(float dt); - bool isActive() const; + bool isEnabled() const; bool getCollideConnected() const; diff --git a/src/modules/physics/box2d/MouseJoint.cpp b/src/modules/physics/box2d/MouseJoint.cpp index 814e507e2..49f2d5f5f 100644 --- a/src/modules/physics/box2d/MouseJoint.cpp +++ b/src/modules/physics/box2d/MouseJoint.cpp @@ -78,28 +78,28 @@ float MouseJoint::getMaxForce() const return Physics::scaleUp(joint->GetMaxForce()); } -void MouseJoint::setFrequency(float hz) +void MouseJoint::setStiffness(float hz) { - // This is kind of a crappy check. The frequency is used in an internal + // This is kind of a crappy check. The Stiffness is used in an internal // box2d calculation whose result must be > FLT_EPSILON, but other variables // go into that calculation... if (hz <= FLT_EPSILON * 2) - throw love::Exception("MouseJoint frequency must be a positive number."); + throw love::Exception("MouseJoint Stiffness must be a positive number."); joint->SetStiffness(hz); } -float MouseJoint::getFrequency() const +float MouseJoint::getStiffness() const { return joint->GetStiffness(); } -void MouseJoint::setDampingRatio(float d) +void MouseJoint::setDamping(float d) { joint->SetDamping(d); } -float MouseJoint::getDampingRatio() const +float MouseJoint::getDamping() const { return joint->GetDamping(); } diff --git a/src/modules/physics/box2d/MouseJoint.h b/src/modules/physics/box2d/MouseJoint.h index 648f26eab..633df0282 100644 --- a/src/modules/physics/box2d/MouseJoint.h +++ b/src/modules/physics/box2d/MouseJoint.h @@ -78,24 +78,24 @@ public: /** * Sets the response speed. **/ - void setFrequency(float hz); + void setStiffness(float hz); /** * Gets the response speed. **/ - float getFrequency() const; + float getStiffness() const; /** * Sets the damping ratio. * 0 = no damping, 1 = critical damping. **/ - void setDampingRatio(float d); + void setDamping(float d); /** * Gets the damping ratio. * 0 = no damping, 1 = critical damping. **/ - float getDampingRatio() const; + float getDamping() const; virtual Body *getBodyA() const; virtual Body *getBodyB() const; diff --git a/src/modules/physics/box2d/WeldJoint.cpp b/src/modules/physics/box2d/WeldJoint.cpp index efdc6e948..df304596a 100644 --- a/src/modules/physics/box2d/WeldJoint.cpp +++ b/src/modules/physics/box2d/WeldJoint.cpp @@ -66,22 +66,22 @@ void WeldJoint::init(b2WeldJointDef &def, Body *body1, Body *body2, float xA, fl def.collideConnected = collideConnected; } -void WeldJoint::setFrequency(float hz) +void WeldJoint::setStiffness(float hz) { joint->SetStiffness(hz); } -float WeldJoint::getFrequency() const +float WeldJoint::getStiffness() const { return joint->GetStiffness(); } -void WeldJoint::setDampingRatio(float d) +void WeldJoint::setDamping(float d) { joint->SetDamping(d); } -float WeldJoint::getDampingRatio() const +float WeldJoint::getDamping() const { return joint->GetDamping(); } diff --git a/src/modules/physics/box2d/WeldJoint.h b/src/modules/physics/box2d/WeldJoint.h index a6e7714c0..d269549e3 100644 --- a/src/modules/physics/box2d/WeldJoint.h +++ b/src/modules/physics/box2d/WeldJoint.h @@ -52,24 +52,24 @@ public: /** * Sets the response speed. **/ - void setFrequency(float hz); + void setStiffness(float hz); /** * Gets the response speed. **/ - float getFrequency() const; + float getStiffness() const; /** * Sets the damping ratio. * 0 = no damping, 1 = critical damping. **/ - void setDampingRatio(float d); + void setDamping(float d); /** * Gets the damping ratio. * 0 = no damping, 1 = critical damping. **/ - float getDampingRatio() const; + float getDamping() const; /** * Gets the reference angle. diff --git a/src/modules/physics/box2d/WheelJoint.cpp b/src/modules/physics/box2d/WheelJoint.cpp index 1d3035ee9..092b6ccf8 100644 --- a/src/modules/physics/box2d/WheelJoint.cpp +++ b/src/modules/physics/box2d/WheelJoint.cpp @@ -95,22 +95,22 @@ float WheelJoint::getMotorTorque(float inv_dt) const return Physics::scaleUp(Physics::scaleUp(joint->GetMotorTorque(inv_dt))); } -void WheelJoint::setSpringFrequency(float hz) +void WheelJoint::setStiffness(float hz) { joint->SetStiffness(hz); } -float WheelJoint::getSpringFrequency() const +float WheelJoint::getStiffness() const { return joint->GetStiffness(); } -void WheelJoint::setSpringDampingRatio(float ratio) +void WheelJoint::setDamping(float ratio) { joint->SetDamping(ratio); } -float WheelJoint::getSpringDampingRatio() const +float WheelJoint::getDamping() const { return joint->GetDamping(); } diff --git a/src/modules/physics/box2d/WheelJoint.h b/src/modules/physics/box2d/WheelJoint.h index 0ee597b3e..fe2ecc4a6 100644 --- a/src/modules/physics/box2d/WheelJoint.h +++ b/src/modules/physics/box2d/WheelJoint.h @@ -99,22 +99,22 @@ public: * Set the spring frequency, in hertz. Setting the frequency to 0 * disables the spring. **/ - void setSpringFrequency(float hz); + void setStiffness(float hz); /** * Get the spring frequency, in hertz. **/ - float getSpringFrequency() const; + float getStiffness() const; /** * Set the spring damping ratio. **/ - void setSpringDampingRatio(float ratio); + void setDamping(float ratio); /** * Get the spring damping ratio. **/ - float getSpringDampingRatio() const; + float getDamping() const; /** * Gets the axis unit vector, relative to body1. From 09db462fd6ec07dfdb39d7968aac02750ca190ce Mon Sep 17 00:00:00 2001 From: Garrett Brown Date: Sun, 16 Aug 2020 19:01:59 -0400 Subject: [PATCH 04/57] Fixes --- src/libraries/Box2D/Box2D.h | 1 + src/libraries/Box2D/Common/b2_settings.cpp | 8 ++++ src/modules/physics/box2d/Body.cpp | 2 +- src/modules/physics/box2d/Body.h | 2 +- src/modules/physics/box2d/ChainShape.cpp | 12 ++--- src/modules/physics/box2d/ChainShape.h | 4 +- src/modules/physics/box2d/EdgeShape.cpp | 12 ++--- src/modules/physics/box2d/EdgeShape.h | 4 +- src/modules/physics/box2d/Physics.cpp | 30 ++++++++++-- src/modules/physics/box2d/wrap_Body.cpp | 4 +- src/modules/physics/box2d/wrap_ChainShape.cpp | 46 ++++++------------- .../physics/box2d/wrap_DistanceJoint.cpp | 16 +++---- src/modules/physics/box2d/wrap_EdgeShape.cpp | 46 ++++++------------- src/modules/physics/box2d/wrap_MouseJoint.cpp | 16 +++---- src/modules/physics/box2d/wrap_WeldJoint.cpp | 16 +++---- src/modules/physics/box2d/wrap_WheelJoint.cpp | 16 +++---- 16 files changed, 111 insertions(+), 124 deletions(-) diff --git a/src/libraries/Box2D/Box2D.h b/src/libraries/Box2D/Box2D.h index 71db86c58..516818f82 100644 --- a/src/libraries/Box2D/Box2D.h +++ b/src/libraries/Box2D/Box2D.h @@ -43,6 +43,7 @@ #include "b2_time_step.h" #include "b2_world.h" #include "b2_world_callbacks.h" +#include "b2_distance.h" #include "b2_distance_joint.h" #include "b2_friction_joint.h" diff --git a/src/libraries/Box2D/Common/b2_settings.cpp b/src/libraries/Box2D/Common/b2_settings.cpp index 11436f7de..2b8565c9e 100644 --- a/src/libraries/Box2D/Common/b2_settings.cpp +++ b/src/libraries/Box2D/Common/b2_settings.cpp @@ -27,6 +27,8 @@ #include #include +#include "common/Exception.h" + b2Version b2_version = {2, 4, 0}; // Memory allocators. Modify these to use your own allocator. @@ -75,3 +77,9 @@ void b2CloseDump() fclose(b2_dumpFile); b2_dumpFile = nullptr; } + +void loveAssert(bool test, const char* teststr) +{ + if (!test) + throw love::Exception("Box2D assertion failed: %s", teststr); +} diff --git a/src/modules/physics/box2d/Body.cpp b/src/modules/physics/box2d/Body.cpp index abba1a202..c61368636 100644 --- a/src/modules/physics/box2d/Body.cpp +++ b/src/modules/physics/box2d/Body.cpp @@ -390,7 +390,7 @@ bool Body::isSleepingAllowed() const return body->IsSleepingAllowed(); } -void Body::SetEnabled(bool enabled) +void Body::setEnabled(bool enabled) { body->SetEnabled(enabled); } diff --git a/src/modules/physics/box2d/Body.h b/src/modules/physics/box2d/Body.h index f5281c486..723da4002 100644 --- a/src/modules/physics/box2d/Body.h +++ b/src/modules/physics/box2d/Body.h @@ -367,7 +367,7 @@ public: /** * Changes the body's active state. **/ - void SetEnabled(bool enabled); + void setEnabled(bool enabled); /** * Changes the body's sleep state. diff --git a/src/modules/physics/box2d/ChainShape.cpp b/src/modules/physics/box2d/ChainShape.cpp index 0d2a83de6..114e40beb 100644 --- a/src/modules/physics/box2d/ChainShape.cpp +++ b/src/modules/physics/box2d/ChainShape.cpp @@ -57,22 +57,18 @@ void ChainShape::setPreviousVertex(float x, float y) c->m_prevVertex = Physics::scaleDown(v); } -void ChainShape::getNextVertex(float &x, float &y) const +b2Vec2 ChainShape::getNextVertex() const { b2ChainShape *c = (b2ChainShape *)shape; - b2Vec2 v = Physics::scaleUp(c->m_nextVertex); - x = v.x; - y = v.y; + return Physics::scaleUp(c->m_nextVertex); } -void ChainShape::getPreviousVertex(float &x, float &y) const +b2Vec2 ChainShape::getPreviousVertex() const { b2ChainShape *c = (b2ChainShape *)shape; - b2Vec2 v = Physics::scaleUp(c->m_prevVertex); - x = v.x; - y = v.y; + return Physics::scaleUp(c->m_prevVertex); } EdgeShape *ChainShape::getChildEdge(int index) const diff --git a/src/modules/physics/box2d/ChainShape.h b/src/modules/physics/box2d/ChainShape.h index 67d7e7a7b..3afbc7365 100644 --- a/src/modules/physics/box2d/ChainShape.h +++ b/src/modules/physics/box2d/ChainShape.h @@ -68,12 +68,12 @@ public: /** * Gets the vertex that follows the last vertex. **/ - void getNextVertex(float &x, float &y) const; + b2Vec2 getNextVertex() const; /** * Gets the vertex that precedes the first vertex. **/ - void getPreviousVertex(float &x, float &y) const; + b2Vec2 getPreviousVertex() const; /** * Returns a child EdgeShape. diff --git a/src/modules/physics/box2d/EdgeShape.cpp b/src/modules/physics/box2d/EdgeShape.cpp index 5810851e7..aad7a36e2 100644 --- a/src/modules/physics/box2d/EdgeShape.cpp +++ b/src/modules/physics/box2d/EdgeShape.cpp @@ -50,13 +50,11 @@ void EdgeShape::setNextVertex(float x, float y) e->m_vertex3 = Physics::scaleDown(v); } -void EdgeShape::getNextVertex(float &x, float &y) const +b2Vec2 EdgeShape::getNextVertex() const { b2EdgeShape *e = (b2EdgeShape *)shape; - b2Vec2 v = Physics::scaleUp(e->m_vertex3); - x = v.x; - y = v.y; + return Physics::scaleUp(e->m_vertex3); } void EdgeShape::setPreviousVertex(float x, float y) @@ -66,13 +64,11 @@ void EdgeShape::setPreviousVertex(float x, float y) e->m_vertex0 = Physics::scaleDown(v); } -void EdgeShape::getPreviousVertex(float &x, float &y) const +b2Vec2 EdgeShape::getPreviousVertex() const { b2EdgeShape *e = (b2EdgeShape *)shape; - b2Vec2 v = Physics::scaleUp(e->m_vertex0); - x = v.x; - y = v.y; + return Physics::scaleUp(e->m_vertex0); } int EdgeShape::getPoints(lua_State *L) diff --git a/src/modules/physics/box2d/EdgeShape.h b/src/modules/physics/box2d/EdgeShape.h index 591606686..ac15b940b 100644 --- a/src/modules/physics/box2d/EdgeShape.h +++ b/src/modules/physics/box2d/EdgeShape.h @@ -50,10 +50,10 @@ public: virtual ~EdgeShape(); void setNextVertex(float x, float y); - void getNextVertex(float &x, float &y) const; + b2Vec2 getNextVertex() const; void setPreviousVertex(float x, float y); - void getPreviousVertex(float &x, float &y) const; + b2Vec2 getPreviousVertex() const; /** * Returns the transformed points of the edge shape. diff --git a/src/modules/physics/box2d/Physics.cpp b/src/modules/physics/box2d/Physics.cpp index 4bc447bc7..33af95be1 100644 --- a/src/modules/physics/box2d/Physics.cpp +++ b/src/modules/physics/box2d/Physics.cpp @@ -160,7 +160,7 @@ int Physics::newChainShape(lua_State *L) if (istable) argc = (int) luax_objlen(L, 2); - if (argc % 2 != 0) + if (argc == 0 || argc % 2 != 0) return luaL_error(L, "Number of vertex components must be a multiple of two."); int vcount = argc/2; @@ -296,9 +296,31 @@ Fixture *Physics::newFixture(Body *body, Shape *shape, float density) int Physics::getDistance(lua_State *L) { - Fixture *fixtureA = luax_checktype(L, 1); - Fixture *fixtureB = luax_checktype(L, 2); - return 0; + Fixture* fixtureA = luax_checktype(L, 1); + Fixture* fixtureB = luax_checktype(L, 2); + b2DistanceProxy pA, pB; + b2DistanceInput i; + b2DistanceOutput o; + b2SimplexCache c; + c.count = 0; + + luax_catchexcept(L, [&]() { + pA.Set(fixtureA->fixture->GetShape(), 0); + pB.Set(fixtureB->fixture->GetShape(), 0); + i.proxyA = pA; + i.proxyB = pB; + i.transformA = fixtureA->fixture->GetBody()->GetTransform(); + i.transformB = fixtureB->fixture->GetBody()->GetTransform(); + i.useRadii = true; + b2Distance(&o, &c, &i); + }); + + lua_pushnumber(L, Physics::scaleUp(o.distance)); + lua_pushnumber(L, Physics::scaleUp(o.pointA.x)); + lua_pushnumber(L, Physics::scaleUp(o.pointA.y)); + lua_pushnumber(L, Physics::scaleUp(o.pointB.x)); + lua_pushnumber(L, Physics::scaleUp(o.pointB.y)); + return 5; } void Physics::setMeter(float scale) diff --git a/src/modules/physics/box2d/wrap_Body.cpp b/src/modules/physics/box2d/wrap_Body.cpp index 54703225e..67b9d9126 100644 --- a/src/modules/physics/box2d/wrap_Body.cpp +++ b/src/modules/physics/box2d/wrap_Body.cpp @@ -490,7 +490,7 @@ int w_Body_setBullet(lua_State *L) int w_Body_isActive(lua_State *L) { Body *t = luax_checkbody(L, 1); - luax_pushboolean(L, t->isActive()); + luax_pushboolean(L, t->isEnabled()); return 1; } @@ -520,7 +520,7 @@ int w_Body_setActive(lua_State *L) { Body *t = luax_checkbody(L, 1); bool b = luax_checkboolean(L, 2); - luax_catchexcept(L, [&](){ t->setActive(b); }); + luax_catchexcept(L, [&](){ t->setEnabled(b); }); return 0; } diff --git a/src/modules/physics/box2d/wrap_ChainShape.cpp b/src/modules/physics/box2d/wrap_ChainShape.cpp index 02d823aa7..9f95e60ab 100644 --- a/src/modules/physics/box2d/wrap_ChainShape.cpp +++ b/src/modules/physics/box2d/wrap_ChainShape.cpp @@ -37,28 +37,18 @@ ChainShape *luax_checkchainshape(lua_State *L, int idx) int w_ChainShape_setNextVertex(lua_State *L) { ChainShape *c = luax_checkchainshape(L, 1); - if (lua_isnoneornil(L, 2)) - c->setNextVertex(); - else - { - float x = (float)luaL_checknumber(L, 2); - float y = (float)luaL_checknumber(L, 3); - luax_catchexcept(L, [&](){ c->setNextVertex(x, y); }); - } + float x = (float)luaL_checknumber(L, 2); + float y = (float)luaL_checknumber(L, 3); + luax_catchexcept(L, [&](){ c->setNextVertex(x, y); }); return 0; } int w_ChainShape_setPreviousVertex(lua_State *L) { ChainShape *c = luax_checkchainshape(L, 1); - if (lua_isnoneornil(L, 2)) - c->setPreviousVertex(); - else - { - float x = (float)luaL_checknumber(L, 2); - float y = (float)luaL_checknumber(L, 3); - luax_catchexcept(L, [&](){ c->setPreviousVertex(x, y); }); - } + float x = (float)luaL_checknumber(L, 2); + float y = (float)luaL_checknumber(L, 3); + luax_catchexcept(L, [&](){ c->setPreviousVertex(x, y); }); return 0; } @@ -95,27 +85,19 @@ int w_ChainShape_getPoint(lua_State *L) int w_ChainShape_getNextVertex(lua_State *L) { ChainShape *c = luax_checkchainshape(L, 1); - float x, y; - if (c->getNextVertex(x, y)) - { - lua_pushnumber(L, x); - lua_pushnumber(L, y); - return 2; - } - return 0; + b2Vec2 v = c->getNextVertex(); + lua_pushnumber(L, v.x); + lua_pushnumber(L, v.y); + return 2; } int w_ChainShape_getPreviousVertex(lua_State *L) { ChainShape *c = luax_checkchainshape(L, 1); - float x, y; - if (c->getPreviousVertex(x, y)) - { - lua_pushnumber(L, x); - lua_pushnumber(L, y); - return 2; - } - return 0; + b2Vec2 v = c->getPreviousVertex(); + lua_pushnumber(L, v.x); + lua_pushnumber(L, v.y); + return 2; } int w_ChainShape_getPoints(lua_State *L) diff --git a/src/modules/physics/box2d/wrap_DistanceJoint.cpp b/src/modules/physics/box2d/wrap_DistanceJoint.cpp index 615665922..1885d2d04 100644 --- a/src/modules/physics/box2d/wrap_DistanceJoint.cpp +++ b/src/modules/physics/box2d/wrap_DistanceJoint.cpp @@ -50,18 +50,18 @@ int w_DistanceJoint_getLength(lua_State *L) return 1; } -int w_DistanceJoint_setFrequency(lua_State *L) +int w_DistanceJoint_setStiffness(lua_State *L) { DistanceJoint *t = luax_checkdistancejoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setFrequency(arg1); + t->setStiffness(arg1); return 0; } -int w_DistanceJoint_getFrequency(lua_State *L) +int w_DistanceJoint_getStiffness(lua_State *L) { DistanceJoint *t = luax_checkdistancejoint(L, 1); - lua_pushnumber(L, t->getFrequency()); + lua_pushnumber(L, t->getStiffness()); return 1; } @@ -69,14 +69,14 @@ int w_DistanceJoint_setDampingRatio(lua_State *L) { DistanceJoint *t = luax_checkdistancejoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setDampingRatio(arg1); + t->setDamping(arg1); return 0; } int w_DistanceJoint_getDampingRatio(lua_State *L) { DistanceJoint *t = luax_checkdistancejoint(L, 1); - lua_pushnumber(L, t->getDampingRatio()); + lua_pushnumber(L, t->getDamping()); return 1; } @@ -84,8 +84,8 @@ static const luaL_Reg w_DistanceJoint_functions[] = { { "setLength", w_DistanceJoint_setLength }, { "getLength", w_DistanceJoint_getLength }, - { "setFrequency", w_DistanceJoint_setFrequency }, - { "getFrequency", w_DistanceJoint_getFrequency }, + { "setStiffness", w_DistanceJoint_setStiffness }, + { "getStiffness", w_DistanceJoint_getStiffness }, { "setDampingRatio", w_DistanceJoint_setDampingRatio }, { "getDampingRatio", w_DistanceJoint_getDampingRatio }, { 0, 0 } diff --git a/src/modules/physics/box2d/wrap_EdgeShape.cpp b/src/modules/physics/box2d/wrap_EdgeShape.cpp index 8d531d5cd..548fd82a2 100644 --- a/src/modules/physics/box2d/wrap_EdgeShape.cpp +++ b/src/modules/physics/box2d/wrap_EdgeShape.cpp @@ -35,55 +35,37 @@ EdgeShape *luax_checkedgeshape(lua_State *L, int idx) int w_EdgeShape_setNextVertex(lua_State *L) { EdgeShape *t = luax_checkedgeshape(L, 1); - if (lua_isnoneornil(L, 2)) - t->setNextVertex(); - else - { - float x = (float)luaL_checknumber(L, 2); - float y = (float)luaL_checknumber(L, 3); - t->setNextVertex(x, y); - } + float x = (float)luaL_checknumber(L, 2); + float y = (float)luaL_checknumber(L, 3); + t->setNextVertex(x, y); return 0; } int w_EdgeShape_setPreviousVertex(lua_State *L) { EdgeShape *t = luax_checkedgeshape(L, 1); - if (lua_isnoneornil(L, 2)) - t->setPreviousVertex(); - else - { - float x = (float)luaL_checknumber(L, 2); - float y = (float)luaL_checknumber(L, 3); - t->setPreviousVertex(x, y); - } + float x = (float)luaL_checknumber(L, 2); + float y = (float)luaL_checknumber(L, 3); + t->setPreviousVertex(x, y); return 0; } int w_EdgeShape_getNextVertex(lua_State *L) { EdgeShape *t = luax_checkedgeshape(L, 1); - float x, y; - if (t->getNextVertex(x, y)) - { - lua_pushnumber(L, x); - lua_pushnumber(L, y); - return 2; - } - return 0; + b2Vec2 v = t->getNextVertex(); + lua_pushnumber(L, v.x); + lua_pushnumber(L, v.y); + return 2; } int w_EdgeShape_getPreviousVertex(lua_State *L) { EdgeShape *t = luax_checkedgeshape(L, 1); - float x, y; - if (t->getPreviousVertex(x, y)) - { - lua_pushnumber(L, x); - lua_pushnumber(L, y); - return 2; - } - return 0; + b2Vec2 v = t->getPreviousVertex(); + lua_pushnumber(L, v.x); + lua_pushnumber(L, v.y); + return 2; } int w_EdgeShape_getPoints(lua_State *L) diff --git a/src/modules/physics/box2d/wrap_MouseJoint.cpp b/src/modules/physics/box2d/wrap_MouseJoint.cpp index 023199cb2..0e9a3b333 100644 --- a/src/modules/physics/box2d/wrap_MouseJoint.cpp +++ b/src/modules/physics/box2d/wrap_MouseJoint.cpp @@ -66,18 +66,18 @@ int w_MouseJoint_getMaxForce(lua_State *L) return 1; } -int w_MouseJoint_setFrequency(lua_State *L) +int w_MouseJoint_setStiffness(lua_State *L) { MouseJoint *t = luax_checkmousejoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - luax_catchexcept(L, [&]() { t->setFrequency(arg1); }); + luax_catchexcept(L, [&]() { t->setStiffness(arg1); }); return 0; } -int w_MouseJoint_getFrequency(lua_State *L) +int w_MouseJoint_getStiffness(lua_State *L) { MouseJoint *t = luax_checkmousejoint(L, 1); - lua_pushnumber(L, t->getFrequency()); + lua_pushnumber(L, t->getStiffness()); return 1; } @@ -85,14 +85,14 @@ int w_MouseJoint_setDampingRatio(lua_State *L) { MouseJoint *t = luax_checkmousejoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setDampingRatio(arg1); + t->setDamping(arg1); return 0; } int w_MouseJoint_getDampingRatio(lua_State *L) { MouseJoint *t = luax_checkmousejoint(L, 1); - lua_pushnumber(L, t->getDampingRatio()); + lua_pushnumber(L, t->getDamping()); return 1; } @@ -102,8 +102,8 @@ static const luaL_Reg w_MouseJoint_functions[] = { "getTarget", w_MouseJoint_getTarget }, { "setMaxForce", w_MouseJoint_setMaxForce }, { "getMaxForce", w_MouseJoint_getMaxForce }, - { "setFrequency", w_MouseJoint_setFrequency }, - { "getFrequency", w_MouseJoint_getFrequency }, + { "setStiffness", w_MouseJoint_setStiffness }, + { "getStiffness", w_MouseJoint_getStiffness }, { "setDampingRatio", w_MouseJoint_setDampingRatio }, { "getDampingRatio", w_MouseJoint_getDampingRatio }, { 0, 0 } diff --git a/src/modules/physics/box2d/wrap_WeldJoint.cpp b/src/modules/physics/box2d/wrap_WeldJoint.cpp index ada93c2d5..123e36e37 100644 --- a/src/modules/physics/box2d/wrap_WeldJoint.cpp +++ b/src/modules/physics/box2d/wrap_WeldJoint.cpp @@ -35,18 +35,18 @@ WeldJoint *luax_checkweldjoint(lua_State *L, int idx) return j; } -int w_WeldJoint_setFrequency(lua_State *L) +int w_WeldJoint_setStiffness(lua_State *L) { WeldJoint *t = luax_checkweldjoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setFrequency(arg1); + t->setStiffness(arg1); return 0; } -int w_WeldJoint_getFrequency(lua_State *L) +int w_WeldJoint_getStiffness(lua_State *L) { WeldJoint *t = luax_checkweldjoint(L, 1); - lua_pushnumber(L, t->getFrequency()); + lua_pushnumber(L, t->getStiffness()); return 1; } @@ -54,14 +54,14 @@ int w_WeldJoint_setDampingRatio(lua_State *L) { WeldJoint *t = luax_checkweldjoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setDampingRatio(arg1); + t->setDamping(arg1); return 0; } int w_WeldJoint_getDampingRatio(lua_State *L) { WeldJoint *t = luax_checkweldjoint(L, 1); - lua_pushnumber(L, t->getDampingRatio()); + lua_pushnumber(L, t->getDamping()); return 1; } @@ -74,8 +74,8 @@ int w_WeldJoint_getReferenceAngle(lua_State *L) static const luaL_Reg w_WeldJoint_functions[] = { - { "setFrequency", w_WeldJoint_setFrequency }, - { "getFrequency", w_WeldJoint_getFrequency }, + { "setStiffness", w_WeldJoint_setStiffness }, + { "getStiffness", w_WeldJoint_getStiffness }, { "setDampingRatio", w_WeldJoint_setDampingRatio }, { "getDampingRatio", w_WeldJoint_getDampingRatio }, { "getReferenceAngle", w_WeldJoint_getReferenceAngle }, diff --git a/src/modules/physics/box2d/wrap_WheelJoint.cpp b/src/modules/physics/box2d/wrap_WheelJoint.cpp index 11aef43f7..1ea4e9549 100644 --- a/src/modules/physics/box2d/wrap_WheelJoint.cpp +++ b/src/modules/physics/box2d/wrap_WheelJoint.cpp @@ -102,18 +102,18 @@ int w_WheelJoint_getMotorTorque(lua_State *L) return 1; } -int w_WheelJoint_setSpringFrequency(lua_State *L) +int w_WheelJoint_setSpringStiffness(lua_State *L) { WheelJoint *t = luax_checkwheeljoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setSpringFrequency(arg1); + t->setStiffness(arg1); return 0; } -int w_WheelJoint_getSpringFrequency(lua_State *L) +int w_WheelJoint_getSpringStiffness(lua_State *L) { WheelJoint *t = luax_checkwheeljoint(L, 1); - lua_pushnumber(L, t->getSpringFrequency()); + lua_pushnumber(L, t->getStiffness()); return 1; } @@ -121,14 +121,14 @@ int w_WheelJoint_setSpringDampingRatio(lua_State *L) { WheelJoint *t = luax_checkwheeljoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setSpringDampingRatio(arg1); + t->setDamping(arg1); return 0; } int w_WheelJoint_getSpringDampingRatio(lua_State *L) { WheelJoint *t = luax_checkwheeljoint(L, 1); - lua_pushnumber(L, t->getSpringDampingRatio()); + lua_pushnumber(L, t->getDamping()); return 1; } @@ -150,8 +150,8 @@ static const luaL_Reg w_WheelJoint_functions[] = { "setMaxMotorTorque", w_WheelJoint_setMaxMotorTorque }, { "getMaxMotorTorque", w_WheelJoint_getMaxMotorTorque }, { "getMotorTorque", w_WheelJoint_getMotorTorque }, - { "setSpringFrequency", w_WheelJoint_setSpringFrequency }, - { "getSpringFrequency", w_WheelJoint_getSpringFrequency }, + { "setSpringStiffness", w_WheelJoint_setSpringStiffness }, + { "getSpringStiffness", w_WheelJoint_getSpringStiffness }, { "setSpringDampingRatio", w_WheelJoint_setSpringDampingRatio }, { "getSpringDampingRatio", w_WheelJoint_getSpringDampingRatio }, { "getAxis", w_WheelJoint_getAxis }, From 8f4476ca3d29a8ab437746bd9773a9998a81eb4f Mon Sep 17 00:00:00 2001 From: Garrett Brown Date: Sun, 16 Aug 2020 19:12:56 -0400 Subject: [PATCH 05/57] Add one sided edge support. Just not sure if the ghost vertices are fine. --- src/modules/physics/box2d/Physics.cpp | 13 +++++++++++-- src/modules/physics/box2d/Physics.h | 2 +- src/modules/physics/box2d/wrap_Physics.cpp | 3 ++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/modules/physics/box2d/Physics.cpp b/src/modules/physics/box2d/Physics.cpp index 33af95be1..c47bdc517 100644 --- a/src/modules/physics/box2d/Physics.cpp +++ b/src/modules/physics/box2d/Physics.cpp @@ -83,10 +83,19 @@ PolygonShape *Physics::newRectangleShape(float x, float y, float w, float h, flo return new PolygonShape(s); } -EdgeShape *Physics::newEdgeShape(float x1, float y1, float x2, float y2) +EdgeShape *Physics::newEdgeShape(float x1, float y1, float x2, float y2, bool oneSided) { b2EdgeShape *s = new b2EdgeShape(); - s->SetTwoSided(Physics::scaleDown(b2Vec2(x1, y1)), Physics::scaleDown(b2Vec2(x2, y2))); + if (oneSided) + { + b2Vec2 v1 = Physics::scaleDown(b2Vec2(x1, y1)); + b2Vec2 v2 = Physics::scaleDown(b2Vec2(x2, y2)); + s->SetOneSided(v1, v1, v2, v2); + } + else + { + s->SetTwoSided(Physics::scaleDown(b2Vec2(x1, y1)), Physics::scaleDown(b2Vec2(x2, y2))); + } return new EdgeShape(s); } diff --git a/src/modules/physics/box2d/Physics.h b/src/modules/physics/box2d/Physics.h index cec254d29..151fb5f86 100644 --- a/src/modules/physics/box2d/Physics.h +++ b/src/modules/physics/box2d/Physics.h @@ -140,7 +140,7 @@ public: * @param x2 The x coordinate of the second point. * @param y2 The y coordinate of the second point. **/ - EdgeShape *newEdgeShape(float x1, float y1, float x2, float y2); + EdgeShape *newEdgeShape(float x1, float y1, float x2, float y2, bool oneSided); /** * Creates a new PolygonShape from a variable number of vertices. diff --git a/src/modules/physics/box2d/wrap_Physics.cpp b/src/modules/physics/box2d/wrap_Physics.cpp index c267fd817..7782c8037 100644 --- a/src/modules/physics/box2d/wrap_Physics.cpp +++ b/src/modules/physics/box2d/wrap_Physics.cpp @@ -160,8 +160,9 @@ int w_newEdgeShape(lua_State *L) float y1 = (float)luaL_checknumber(L, 2); float x2 = (float)luaL_checknumber(L, 3); float y2 = (float)luaL_checknumber(L, 4); + bool oneSided = luax_optboolean(L, 5, false); EdgeShape *shape; - luax_catchexcept(L, [&](){ shape = instance()->newEdgeShape(x1, y1, x2, y2); }); + luax_catchexcept(L, [&](){ shape = instance()->newEdgeShape(x1, y1, x2, y2, oneSided); }); luax_pushtype(L, shape); shape->release(); return 1; From 350054e19091b4e99bd46d1218c0b9aaebaa79d5 Mon Sep 17 00:00:00 2001 From: Garrett Brown Date: Sun, 16 Aug 2020 19:28:20 -0400 Subject: [PATCH 06/57] Rename Box2D folder to box2d --- CMakeLists.txt | 114 +++++++++--------- src/libraries/{Box2D => box2d}/Box2D.h | 0 .../Collision/b2_broad_phase.cpp | 0 .../Collision/b2_chain_shape.cpp | 0 .../Collision/b2_circle_shape.cpp | 0 .../Collision/b2_collide_circle.cpp | 0 .../Collision/b2_collide_edge.cpp | 0 .../Collision/b2_collide_polygon.cpp | 0 .../Collision/b2_collision.cpp | 0 .../Collision/b2_distance.cpp | 0 .../Collision/b2_dynamic_tree.cpp | 0 .../Collision/b2_edge_shape.cpp | 0 .../Collision/b2_polygon_shape.cpp | 0 .../Collision/b2_time_of_impact.cpp | 0 .../Common/b2_block_allocator.cpp | 0 .../{Box2D => box2d}/Common/b2_draw.cpp | 0 .../{Box2D => box2d}/Common/b2_math.cpp | 0 .../{Box2D => box2d}/Common/b2_settings.cpp | 0 .../Common/b2_stack_allocator.cpp | 0 .../{Box2D => box2d}/Common/b2_timer.cpp | 0 .../{Box2D => box2d}/Dynamics/b2_body.cpp | 0 .../Dynamics/b2_chain_circle_contact.cpp | 0 .../Dynamics/b2_chain_circle_contact.h | 0 .../Dynamics/b2_chain_polygon_contact.cpp | 0 .../Dynamics/b2_chain_polygon_contact.h | 0 .../Dynamics/b2_circle_contact.cpp | 0 .../Dynamics/b2_circle_contact.h | 0 .../{Box2D => box2d}/Dynamics/b2_contact.cpp | 0 .../Dynamics/b2_contact_manager.cpp | 0 .../Dynamics/b2_contact_solver.cpp | 0 .../Dynamics/b2_contact_solver.h | 0 .../Dynamics/b2_distance_joint.cpp | 0 .../Dynamics/b2_edge_circle_contact.cpp | 0 .../Dynamics/b2_edge_circle_contact.h | 0 .../Dynamics/b2_edge_polygon_contact.cpp | 0 .../Dynamics/b2_edge_polygon_contact.h | 0 .../{Box2D => box2d}/Dynamics/b2_fixture.cpp | 0 .../Dynamics/b2_friction_joint.cpp | 0 .../Dynamics/b2_gear_joint.cpp | 0 .../{Box2D => box2d}/Dynamics/b2_island.cpp | 0 .../{Box2D => box2d}/Dynamics/b2_island.h | 0 .../{Box2D => box2d}/Dynamics/b2_joint.cpp | 0 .../Dynamics/b2_motor_joint.cpp | 0 .../Dynamics/b2_mouse_joint.cpp | 0 .../Dynamics/b2_polygon_circle_contact.cpp | 0 .../Dynamics/b2_polygon_circle_contact.h | 0 .../Dynamics/b2_polygon_contact.cpp | 0 .../Dynamics/b2_polygon_contact.h | 0 .../Dynamics/b2_prismatic_joint.cpp | 0 .../Dynamics/b2_pulley_joint.cpp | 0 .../Dynamics/b2_revolute_joint.cpp | 0 .../Dynamics/b2_rope_joint.cpp | 0 .../Dynamics/b2_weld_joint.cpp | 0 .../Dynamics/b2_wheel_joint.cpp | 0 .../{Box2D => box2d}/Dynamics/b2_world.cpp | 0 .../Dynamics/b2_world_callbacks.cpp | 0 .../{Box2D => box2d}/README.MODIFIED | 0 .../{Box2D => box2d}/Rope/b2_rope.cpp | 0 .../{Box2D => box2d}/b2_block_allocator.h | 0 src/libraries/{Box2D => box2d}/b2_body.h | 0 .../{Box2D => box2d}/b2_broad_phase.h | 0 .../{Box2D => box2d}/b2_chain_shape.h | 0 .../{Box2D => box2d}/b2_circle_shape.h | 0 src/libraries/{Box2D => box2d}/b2_collision.h | 0 src/libraries/{Box2D => box2d}/b2_contact.h | 0 .../{Box2D => box2d}/b2_contact_manager.h | 0 src/libraries/{Box2D => box2d}/b2_distance.h | 0 .../{Box2D => box2d}/b2_distance_joint.h | 0 src/libraries/{Box2D => box2d}/b2_draw.h | 0 .../{Box2D => box2d}/b2_dynamic_tree.h | 0 .../{Box2D => box2d}/b2_edge_shape.h | 0 src/libraries/{Box2D => box2d}/b2_fixture.h | 0 .../{Box2D => box2d}/b2_friction_joint.h | 0 .../{Box2D => box2d}/b2_gear_joint.h | 0 .../{Box2D => box2d}/b2_growable_stack.h | 0 src/libraries/{Box2D => box2d}/b2_joint.h | 0 src/libraries/{Box2D => box2d}/b2_math.h | 0 .../{Box2D => box2d}/b2_motor_joint.h | 0 .../{Box2D => box2d}/b2_mouse_joint.h | 0 .../{Box2D => box2d}/b2_polygon_shape.h | 0 .../{Box2D => box2d}/b2_prismatic_joint.h | 0 .../{Box2D => box2d}/b2_pulley_joint.h | 0 .../{Box2D => box2d}/b2_revolute_joint.h | 0 src/libraries/{Box2D => box2d}/b2_rope.h | 0 .../{Box2D => box2d}/b2_rope_joint.h | 0 src/libraries/{Box2D => box2d}/b2_settings.h | 0 src/libraries/{Box2D => box2d}/b2_shape.h | 0 .../{Box2D => box2d}/b2_stack_allocator.h | 0 .../{Box2D => box2d}/b2_time_of_impact.h | 0 src/libraries/{Box2D => box2d}/b2_time_step.h | 0 src/libraries/{Box2D => box2d}/b2_timer.h | 0 .../{Box2D => box2d}/b2_weld_joint.h | 0 .../{Box2D => box2d}/b2_wheel_joint.h | 0 src/libraries/{Box2D => box2d}/b2_world.h | 0 .../{Box2D => box2d}/b2_world_callbacks.h | 0 95 files changed, 57 insertions(+), 57 deletions(-) rename src/libraries/{Box2D => box2d}/Box2D.h (100%) rename src/libraries/{Box2D => box2d}/Collision/b2_broad_phase.cpp (100%) rename src/libraries/{Box2D => box2d}/Collision/b2_chain_shape.cpp (100%) rename src/libraries/{Box2D => box2d}/Collision/b2_circle_shape.cpp (100%) rename src/libraries/{Box2D => box2d}/Collision/b2_collide_circle.cpp (100%) rename src/libraries/{Box2D => box2d}/Collision/b2_collide_edge.cpp (100%) rename src/libraries/{Box2D => box2d}/Collision/b2_collide_polygon.cpp (100%) rename src/libraries/{Box2D => box2d}/Collision/b2_collision.cpp (100%) rename src/libraries/{Box2D => box2d}/Collision/b2_distance.cpp (100%) rename src/libraries/{Box2D => box2d}/Collision/b2_dynamic_tree.cpp (100%) rename src/libraries/{Box2D => box2d}/Collision/b2_edge_shape.cpp (100%) rename src/libraries/{Box2D => box2d}/Collision/b2_polygon_shape.cpp (100%) rename src/libraries/{Box2D => box2d}/Collision/b2_time_of_impact.cpp (100%) rename src/libraries/{Box2D => box2d}/Common/b2_block_allocator.cpp (100%) rename src/libraries/{Box2D => box2d}/Common/b2_draw.cpp (100%) rename src/libraries/{Box2D => box2d}/Common/b2_math.cpp (100%) rename src/libraries/{Box2D => box2d}/Common/b2_settings.cpp (100%) rename src/libraries/{Box2D => box2d}/Common/b2_stack_allocator.cpp (100%) rename src/libraries/{Box2D => box2d}/Common/b2_timer.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_body.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_chain_circle_contact.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_chain_circle_contact.h (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_chain_polygon_contact.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_chain_polygon_contact.h (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_circle_contact.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_circle_contact.h (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_contact.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_contact_manager.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_contact_solver.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_contact_solver.h (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_distance_joint.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_edge_circle_contact.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_edge_circle_contact.h (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_edge_polygon_contact.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_edge_polygon_contact.h (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_fixture.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_friction_joint.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_gear_joint.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_island.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_island.h (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_joint.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_motor_joint.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_mouse_joint.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_polygon_circle_contact.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_polygon_circle_contact.h (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_polygon_contact.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_polygon_contact.h (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_prismatic_joint.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_pulley_joint.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_revolute_joint.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_rope_joint.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_weld_joint.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_wheel_joint.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_world.cpp (100%) rename src/libraries/{Box2D => box2d}/Dynamics/b2_world_callbacks.cpp (100%) rename src/libraries/{Box2D => box2d}/README.MODIFIED (100%) rename src/libraries/{Box2D => box2d}/Rope/b2_rope.cpp (100%) rename src/libraries/{Box2D => box2d}/b2_block_allocator.h (100%) rename src/libraries/{Box2D => box2d}/b2_body.h (100%) rename src/libraries/{Box2D => box2d}/b2_broad_phase.h (100%) rename src/libraries/{Box2D => box2d}/b2_chain_shape.h (100%) rename src/libraries/{Box2D => box2d}/b2_circle_shape.h (100%) rename src/libraries/{Box2D => box2d}/b2_collision.h (100%) rename src/libraries/{Box2D => box2d}/b2_contact.h (100%) rename src/libraries/{Box2D => box2d}/b2_contact_manager.h (100%) rename src/libraries/{Box2D => box2d}/b2_distance.h (100%) rename src/libraries/{Box2D => box2d}/b2_distance_joint.h (100%) rename src/libraries/{Box2D => box2d}/b2_draw.h (100%) rename src/libraries/{Box2D => box2d}/b2_dynamic_tree.h (100%) rename src/libraries/{Box2D => box2d}/b2_edge_shape.h (100%) rename src/libraries/{Box2D => box2d}/b2_fixture.h (100%) rename src/libraries/{Box2D => box2d}/b2_friction_joint.h (100%) rename src/libraries/{Box2D => box2d}/b2_gear_joint.h (100%) rename src/libraries/{Box2D => box2d}/b2_growable_stack.h (100%) rename src/libraries/{Box2D => box2d}/b2_joint.h (100%) rename src/libraries/{Box2D => box2d}/b2_math.h (100%) rename src/libraries/{Box2D => box2d}/b2_motor_joint.h (100%) rename src/libraries/{Box2D => box2d}/b2_mouse_joint.h (100%) rename src/libraries/{Box2D => box2d}/b2_polygon_shape.h (100%) rename src/libraries/{Box2D => box2d}/b2_prismatic_joint.h (100%) rename src/libraries/{Box2D => box2d}/b2_pulley_joint.h (100%) rename src/libraries/{Box2D => box2d}/b2_revolute_joint.h (100%) rename src/libraries/{Box2D => box2d}/b2_rope.h (100%) rename src/libraries/{Box2D => box2d}/b2_rope_joint.h (100%) rename src/libraries/{Box2D => box2d}/b2_settings.h (100%) rename src/libraries/{Box2D => box2d}/b2_shape.h (100%) rename src/libraries/{Box2D => box2d}/b2_stack_allocator.h (100%) rename src/libraries/{Box2D => box2d}/b2_time_of_impact.h (100%) rename src/libraries/{Box2D => box2d}/b2_time_step.h (100%) rename src/libraries/{Box2D => box2d}/b2_timer.h (100%) rename src/libraries/{Box2D => box2d}/b2_weld_joint.h (100%) rename src/libraries/{Box2D => box2d}/b2_wheel_joint.h (100%) rename src/libraries/{Box2D => box2d}/b2_world.h (100%) rename src/libraries/{Box2D => box2d}/b2_world_callbacks.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index d1290e393..3c1c6007b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1064,74 +1064,74 @@ source_group("modules\\window\\sdl" FILES ${LOVE_SRC_MODULE_WINDOW_SDL}) # set(LOVE_SRC_3P_BOX2D_ROOT - src/libraries/Box2D/Box2D.h + src/libraries/box2d/Box2D.h ) set(LOVE_SRC_3P_BOX2D_COLLISION - src/libraries/Box2D/collision/b2_broad_phase.cpp - src/libraries/Box2D/collision/b2_chain_shape.cpp - src/libraries/Box2D/collision/b2_circle_shape.cpp - src/libraries/Box2D/collision/b2_collide_circle.cpp - src/libraries/Box2D/collision/b2_collide_edge.cpp - src/libraries/Box2D/collision/b2_collide_polygon.cpp - src/libraries/Box2D/collision/b2_collision.cpp - src/libraries/Box2D/collision/b2_distance.cpp - src/libraries/Box2D/collision/b2_dynamic_tree.cpp - src/libraries/Box2D/collision/b2_edge_shape.cpp - src/libraries/Box2D/collision/b2_polygon_shape.cpp - src/libraries/Box2D/collision/b2_time_of_impact.cpp + src/libraries/box2d/collision/b2_broad_phase.cpp + src/libraries/box2d/collision/b2_chain_shape.cpp + src/libraries/box2d/collision/b2_circle_shape.cpp + src/libraries/box2d/collision/b2_collide_circle.cpp + src/libraries/box2d/collision/b2_collide_edge.cpp + src/libraries/box2d/collision/b2_collide_polygon.cpp + src/libraries/box2d/collision/b2_collision.cpp + src/libraries/box2d/collision/b2_distance.cpp + src/libraries/box2d/collision/b2_dynamic_tree.cpp + src/libraries/box2d/collision/b2_edge_shape.cpp + src/libraries/box2d/collision/b2_polygon_shape.cpp + src/libraries/box2d/collision/b2_time_of_impact.cpp ) set(LOVE_SRC_3P_BOX2D_COMMON - src/libraries/Box2D/common/b2_block_allocator.cpp - src/libraries/Box2D/common/b2_draw.cpp - src/libraries/Box2D/common/b2_math.cpp - src/libraries/Box2D/common/b2_settings.cpp - src/libraries/Box2D/common/b2_stack_allocator.cpp - src/libraries/Box2D/common/b2_timer.cpp + src/libraries/box2d/common/b2_block_allocator.cpp + src/libraries/box2d/common/b2_draw.cpp + src/libraries/box2d/common/b2_math.cpp + src/libraries/box2d/common/b2_settings.cpp + src/libraries/box2d/common/b2_stack_allocator.cpp + src/libraries/box2d/common/b2_timer.cpp ) set(LOVE_SRC_3P_BOX2D_DYNAMICS - src/libraries/Box2D/dynamics/b2_body.cpp - src/libraries/Box2D/dynamics/b2_chain_circle_contact.cpp - src/libraries/Box2D/dynamics/b2_chain_circle_contact.h - src/libraries/Box2D/dynamics/b2_chain_polygon_contact.cpp - src/libraries/Box2D/dynamics/b2_chain_polygon_contact.h - src/libraries/Box2D/dynamics/b2_circle_contact.cpp - src/libraries/Box2D/dynamics/b2_circle_contact.h - src/libraries/Box2D/dynamics/b2_contact.cpp - src/libraries/Box2D/dynamics/b2_contact_manager.cpp - src/libraries/Box2D/dynamics/b2_contact_solver.cpp - src/libraries/Box2D/dynamics/b2_contact_solver.h - src/libraries/Box2D/dynamics/b2_distance_joint.cpp - src/libraries/Box2D/dynamics/b2_edge_circle_contact.cpp - src/libraries/Box2D/dynamics/b2_edge_circle_contact.h - src/libraries/Box2D/dynamics/b2_edge_polygon_contact.cpp - src/libraries/Box2D/dynamics/b2_edge_polygon_contact.h - src/libraries/Box2D/dynamics/b2_fixture.cpp - src/libraries/Box2D/dynamics/b2_friction_joint.cpp - src/libraries/Box2D/dynamics/b2_gear_joint.cpp - src/libraries/Box2D/dynamics/b2_island.cpp - src/libraries/Box2D/dynamics/b2_island.h - src/libraries/Box2D/dynamics/b2_joint.cpp - src/libraries/Box2D/dynamics/b2_motor_joint.cpp - src/libraries/Box2D/dynamics/b2_mouse_joint.cpp - src/libraries/Box2D/dynamics/b2_polygon_circle_contact.cpp - src/libraries/Box2D/dynamics/b2_polygon_circle_contact.h - src/libraries/Box2D/dynamics/b2_polygon_contact.cpp - src/libraries/Box2D/dynamics/b2_polygon_contact.h - src/libraries/Box2D/dynamics/b2_prismatic_joint.cpp - src/libraries/Box2D/dynamics/b2_pulley_joint.cpp - src/libraries/Box2D/dynamics/b2_revolute_joint.cpp - src/libraries/Box2D/dynamics/b2_rope_joint.cpp - src/libraries/Box2D/dynamics/b2_weld_joint.cpp - src/libraries/Box2D/dynamics/b2_wheel_joint.cpp - src/libraries/Box2D/dynamics/b2_world.cpp - src/libraries/Box2D/dynamics/b2_world_callbacks.cpp + src/libraries/box2d/dynamics/b2_body.cpp + src/libraries/box2d/dynamics/b2_chain_circle_contact.cpp + src/libraries/box2d/dynamics/b2_chain_circle_contact.h + src/libraries/box2d/dynamics/b2_chain_polygon_contact.cpp + src/libraries/box2d/dynamics/b2_chain_polygon_contact.h + src/libraries/box2d/dynamics/b2_circle_contact.cpp + src/libraries/box2d/dynamics/b2_circle_contact.h + src/libraries/box2d/dynamics/b2_contact.cpp + src/libraries/box2d/dynamics/b2_contact_manager.cpp + src/libraries/box2d/dynamics/b2_contact_solver.cpp + src/libraries/box2d/dynamics/b2_contact_solver.h + src/libraries/box2d/dynamics/b2_distance_joint.cpp + src/libraries/box2d/dynamics/b2_edge_circle_contact.cpp + src/libraries/box2d/dynamics/b2_edge_circle_contact.h + src/libraries/box2d/dynamics/b2_edge_polygon_contact.cpp + src/libraries/box2d/dynamics/b2_edge_polygon_contact.h + src/libraries/box2d/dynamics/b2_fixture.cpp + src/libraries/box2d/dynamics/b2_friction_joint.cpp + src/libraries/box2d/dynamics/b2_gear_joint.cpp + src/libraries/box2d/dynamics/b2_island.cpp + src/libraries/box2d/dynamics/b2_island.h + src/libraries/box2d/dynamics/b2_joint.cpp + src/libraries/box2d/dynamics/b2_motor_joint.cpp + src/libraries/box2d/dynamics/b2_mouse_joint.cpp + src/libraries/box2d/dynamics/b2_polygon_circle_contact.cpp + src/libraries/box2d/dynamics/b2_polygon_circle_contact.h + src/libraries/box2d/dynamics/b2_polygon_contact.cpp + src/libraries/box2d/dynamics/b2_polygon_contact.h + src/libraries/box2d/dynamics/b2_prismatic_joint.cpp + src/libraries/box2d/dynamics/b2_pulley_joint.cpp + src/libraries/box2d/dynamics/b2_revolute_joint.cpp + src/libraries/box2d/dynamics/b2_rope_joint.cpp + src/libraries/box2d/dynamics/b2_weld_joint.cpp + src/libraries/box2d/dynamics/b2_wheel_joint.cpp + src/libraries/box2d/dynamics/b2_world.cpp + src/libraries/box2d/dynamics/b2_world_callbacks.cpp ) set(LOVE_SRC_3P_BOX2D_ROPE - src/libraries/Box2D/rope/b2_rope.cpp + src/libraries/box2d/rope/b2_rope.cpp ) set(LOVE_SRC_3P_BOX2D @@ -1677,7 +1677,7 @@ set(LOVE_LIB_SRC include_directories( src src/libraries - src/libraries/Box2D + src/libraries/box2D src/modules ${LOVE_INCLUDE_DIRS} ) diff --git a/src/libraries/Box2D/Box2D.h b/src/libraries/box2d/Box2D.h similarity index 100% rename from src/libraries/Box2D/Box2D.h rename to src/libraries/box2d/Box2D.h diff --git a/src/libraries/Box2D/Collision/b2_broad_phase.cpp b/src/libraries/box2d/Collision/b2_broad_phase.cpp similarity index 100% rename from src/libraries/Box2D/Collision/b2_broad_phase.cpp rename to src/libraries/box2d/Collision/b2_broad_phase.cpp diff --git a/src/libraries/Box2D/Collision/b2_chain_shape.cpp b/src/libraries/box2d/Collision/b2_chain_shape.cpp similarity index 100% rename from src/libraries/Box2D/Collision/b2_chain_shape.cpp rename to src/libraries/box2d/Collision/b2_chain_shape.cpp diff --git a/src/libraries/Box2D/Collision/b2_circle_shape.cpp b/src/libraries/box2d/Collision/b2_circle_shape.cpp similarity index 100% rename from src/libraries/Box2D/Collision/b2_circle_shape.cpp rename to src/libraries/box2d/Collision/b2_circle_shape.cpp diff --git a/src/libraries/Box2D/Collision/b2_collide_circle.cpp b/src/libraries/box2d/Collision/b2_collide_circle.cpp similarity index 100% rename from src/libraries/Box2D/Collision/b2_collide_circle.cpp rename to src/libraries/box2d/Collision/b2_collide_circle.cpp diff --git a/src/libraries/Box2D/Collision/b2_collide_edge.cpp b/src/libraries/box2d/Collision/b2_collide_edge.cpp similarity index 100% rename from src/libraries/Box2D/Collision/b2_collide_edge.cpp rename to src/libraries/box2d/Collision/b2_collide_edge.cpp diff --git a/src/libraries/Box2D/Collision/b2_collide_polygon.cpp b/src/libraries/box2d/Collision/b2_collide_polygon.cpp similarity index 100% rename from src/libraries/Box2D/Collision/b2_collide_polygon.cpp rename to src/libraries/box2d/Collision/b2_collide_polygon.cpp diff --git a/src/libraries/Box2D/Collision/b2_collision.cpp b/src/libraries/box2d/Collision/b2_collision.cpp similarity index 100% rename from src/libraries/Box2D/Collision/b2_collision.cpp rename to src/libraries/box2d/Collision/b2_collision.cpp diff --git a/src/libraries/Box2D/Collision/b2_distance.cpp b/src/libraries/box2d/Collision/b2_distance.cpp similarity index 100% rename from src/libraries/Box2D/Collision/b2_distance.cpp rename to src/libraries/box2d/Collision/b2_distance.cpp diff --git a/src/libraries/Box2D/Collision/b2_dynamic_tree.cpp b/src/libraries/box2d/Collision/b2_dynamic_tree.cpp similarity index 100% rename from src/libraries/Box2D/Collision/b2_dynamic_tree.cpp rename to src/libraries/box2d/Collision/b2_dynamic_tree.cpp diff --git a/src/libraries/Box2D/Collision/b2_edge_shape.cpp b/src/libraries/box2d/Collision/b2_edge_shape.cpp similarity index 100% rename from src/libraries/Box2D/Collision/b2_edge_shape.cpp rename to src/libraries/box2d/Collision/b2_edge_shape.cpp diff --git a/src/libraries/Box2D/Collision/b2_polygon_shape.cpp b/src/libraries/box2d/Collision/b2_polygon_shape.cpp similarity index 100% rename from src/libraries/Box2D/Collision/b2_polygon_shape.cpp rename to src/libraries/box2d/Collision/b2_polygon_shape.cpp diff --git a/src/libraries/Box2D/Collision/b2_time_of_impact.cpp b/src/libraries/box2d/Collision/b2_time_of_impact.cpp similarity index 100% rename from src/libraries/Box2D/Collision/b2_time_of_impact.cpp rename to src/libraries/box2d/Collision/b2_time_of_impact.cpp diff --git a/src/libraries/Box2D/Common/b2_block_allocator.cpp b/src/libraries/box2d/Common/b2_block_allocator.cpp similarity index 100% rename from src/libraries/Box2D/Common/b2_block_allocator.cpp rename to src/libraries/box2d/Common/b2_block_allocator.cpp diff --git a/src/libraries/Box2D/Common/b2_draw.cpp b/src/libraries/box2d/Common/b2_draw.cpp similarity index 100% rename from src/libraries/Box2D/Common/b2_draw.cpp rename to src/libraries/box2d/Common/b2_draw.cpp diff --git a/src/libraries/Box2D/Common/b2_math.cpp b/src/libraries/box2d/Common/b2_math.cpp similarity index 100% rename from src/libraries/Box2D/Common/b2_math.cpp rename to src/libraries/box2d/Common/b2_math.cpp diff --git a/src/libraries/Box2D/Common/b2_settings.cpp b/src/libraries/box2d/Common/b2_settings.cpp similarity index 100% rename from src/libraries/Box2D/Common/b2_settings.cpp rename to src/libraries/box2d/Common/b2_settings.cpp diff --git a/src/libraries/Box2D/Common/b2_stack_allocator.cpp b/src/libraries/box2d/Common/b2_stack_allocator.cpp similarity index 100% rename from src/libraries/Box2D/Common/b2_stack_allocator.cpp rename to src/libraries/box2d/Common/b2_stack_allocator.cpp diff --git a/src/libraries/Box2D/Common/b2_timer.cpp b/src/libraries/box2d/Common/b2_timer.cpp similarity index 100% rename from src/libraries/Box2D/Common/b2_timer.cpp rename to src/libraries/box2d/Common/b2_timer.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_body.cpp b/src/libraries/box2d/Dynamics/b2_body.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_body.cpp rename to src/libraries/box2d/Dynamics/b2_body.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_chain_circle_contact.cpp b/src/libraries/box2d/Dynamics/b2_chain_circle_contact.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_chain_circle_contact.cpp rename to src/libraries/box2d/Dynamics/b2_chain_circle_contact.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_chain_circle_contact.h b/src/libraries/box2d/Dynamics/b2_chain_circle_contact.h similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_chain_circle_contact.h rename to src/libraries/box2d/Dynamics/b2_chain_circle_contact.h diff --git a/src/libraries/Box2D/Dynamics/b2_chain_polygon_contact.cpp b/src/libraries/box2d/Dynamics/b2_chain_polygon_contact.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_chain_polygon_contact.cpp rename to src/libraries/box2d/Dynamics/b2_chain_polygon_contact.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_chain_polygon_contact.h b/src/libraries/box2d/Dynamics/b2_chain_polygon_contact.h similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_chain_polygon_contact.h rename to src/libraries/box2d/Dynamics/b2_chain_polygon_contact.h diff --git a/src/libraries/Box2D/Dynamics/b2_circle_contact.cpp b/src/libraries/box2d/Dynamics/b2_circle_contact.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_circle_contact.cpp rename to src/libraries/box2d/Dynamics/b2_circle_contact.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_circle_contact.h b/src/libraries/box2d/Dynamics/b2_circle_contact.h similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_circle_contact.h rename to src/libraries/box2d/Dynamics/b2_circle_contact.h diff --git a/src/libraries/Box2D/Dynamics/b2_contact.cpp b/src/libraries/box2d/Dynamics/b2_contact.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_contact.cpp rename to src/libraries/box2d/Dynamics/b2_contact.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_contact_manager.cpp b/src/libraries/box2d/Dynamics/b2_contact_manager.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_contact_manager.cpp rename to src/libraries/box2d/Dynamics/b2_contact_manager.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_contact_solver.cpp b/src/libraries/box2d/Dynamics/b2_contact_solver.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_contact_solver.cpp rename to src/libraries/box2d/Dynamics/b2_contact_solver.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_contact_solver.h b/src/libraries/box2d/Dynamics/b2_contact_solver.h similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_contact_solver.h rename to src/libraries/box2d/Dynamics/b2_contact_solver.h diff --git a/src/libraries/Box2D/Dynamics/b2_distance_joint.cpp b/src/libraries/box2d/Dynamics/b2_distance_joint.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_distance_joint.cpp rename to src/libraries/box2d/Dynamics/b2_distance_joint.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_edge_circle_contact.cpp b/src/libraries/box2d/Dynamics/b2_edge_circle_contact.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_edge_circle_contact.cpp rename to src/libraries/box2d/Dynamics/b2_edge_circle_contact.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_edge_circle_contact.h b/src/libraries/box2d/Dynamics/b2_edge_circle_contact.h similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_edge_circle_contact.h rename to src/libraries/box2d/Dynamics/b2_edge_circle_contact.h diff --git a/src/libraries/Box2D/Dynamics/b2_edge_polygon_contact.cpp b/src/libraries/box2d/Dynamics/b2_edge_polygon_contact.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_edge_polygon_contact.cpp rename to src/libraries/box2d/Dynamics/b2_edge_polygon_contact.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_edge_polygon_contact.h b/src/libraries/box2d/Dynamics/b2_edge_polygon_contact.h similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_edge_polygon_contact.h rename to src/libraries/box2d/Dynamics/b2_edge_polygon_contact.h diff --git a/src/libraries/Box2D/Dynamics/b2_fixture.cpp b/src/libraries/box2d/Dynamics/b2_fixture.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_fixture.cpp rename to src/libraries/box2d/Dynamics/b2_fixture.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_friction_joint.cpp b/src/libraries/box2d/Dynamics/b2_friction_joint.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_friction_joint.cpp rename to src/libraries/box2d/Dynamics/b2_friction_joint.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_gear_joint.cpp b/src/libraries/box2d/Dynamics/b2_gear_joint.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_gear_joint.cpp rename to src/libraries/box2d/Dynamics/b2_gear_joint.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_island.cpp b/src/libraries/box2d/Dynamics/b2_island.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_island.cpp rename to src/libraries/box2d/Dynamics/b2_island.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_island.h b/src/libraries/box2d/Dynamics/b2_island.h similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_island.h rename to src/libraries/box2d/Dynamics/b2_island.h diff --git a/src/libraries/Box2D/Dynamics/b2_joint.cpp b/src/libraries/box2d/Dynamics/b2_joint.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_joint.cpp rename to src/libraries/box2d/Dynamics/b2_joint.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_motor_joint.cpp b/src/libraries/box2d/Dynamics/b2_motor_joint.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_motor_joint.cpp rename to src/libraries/box2d/Dynamics/b2_motor_joint.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_mouse_joint.cpp b/src/libraries/box2d/Dynamics/b2_mouse_joint.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_mouse_joint.cpp rename to src/libraries/box2d/Dynamics/b2_mouse_joint.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_polygon_circle_contact.cpp b/src/libraries/box2d/Dynamics/b2_polygon_circle_contact.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_polygon_circle_contact.cpp rename to src/libraries/box2d/Dynamics/b2_polygon_circle_contact.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_polygon_circle_contact.h b/src/libraries/box2d/Dynamics/b2_polygon_circle_contact.h similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_polygon_circle_contact.h rename to src/libraries/box2d/Dynamics/b2_polygon_circle_contact.h diff --git a/src/libraries/Box2D/Dynamics/b2_polygon_contact.cpp b/src/libraries/box2d/Dynamics/b2_polygon_contact.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_polygon_contact.cpp rename to src/libraries/box2d/Dynamics/b2_polygon_contact.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_polygon_contact.h b/src/libraries/box2d/Dynamics/b2_polygon_contact.h similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_polygon_contact.h rename to src/libraries/box2d/Dynamics/b2_polygon_contact.h diff --git a/src/libraries/Box2D/Dynamics/b2_prismatic_joint.cpp b/src/libraries/box2d/Dynamics/b2_prismatic_joint.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_prismatic_joint.cpp rename to src/libraries/box2d/Dynamics/b2_prismatic_joint.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_pulley_joint.cpp b/src/libraries/box2d/Dynamics/b2_pulley_joint.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_pulley_joint.cpp rename to src/libraries/box2d/Dynamics/b2_pulley_joint.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_revolute_joint.cpp b/src/libraries/box2d/Dynamics/b2_revolute_joint.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_revolute_joint.cpp rename to src/libraries/box2d/Dynamics/b2_revolute_joint.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_rope_joint.cpp b/src/libraries/box2d/Dynamics/b2_rope_joint.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_rope_joint.cpp rename to src/libraries/box2d/Dynamics/b2_rope_joint.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_weld_joint.cpp b/src/libraries/box2d/Dynamics/b2_weld_joint.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_weld_joint.cpp rename to src/libraries/box2d/Dynamics/b2_weld_joint.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_wheel_joint.cpp b/src/libraries/box2d/Dynamics/b2_wheel_joint.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_wheel_joint.cpp rename to src/libraries/box2d/Dynamics/b2_wheel_joint.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_world.cpp b/src/libraries/box2d/Dynamics/b2_world.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_world.cpp rename to src/libraries/box2d/Dynamics/b2_world.cpp diff --git a/src/libraries/Box2D/Dynamics/b2_world_callbacks.cpp b/src/libraries/box2d/Dynamics/b2_world_callbacks.cpp similarity index 100% rename from src/libraries/Box2D/Dynamics/b2_world_callbacks.cpp rename to src/libraries/box2d/Dynamics/b2_world_callbacks.cpp diff --git a/src/libraries/Box2D/README.MODIFIED b/src/libraries/box2d/README.MODIFIED similarity index 100% rename from src/libraries/Box2D/README.MODIFIED rename to src/libraries/box2d/README.MODIFIED diff --git a/src/libraries/Box2D/Rope/b2_rope.cpp b/src/libraries/box2d/Rope/b2_rope.cpp similarity index 100% rename from src/libraries/Box2D/Rope/b2_rope.cpp rename to src/libraries/box2d/Rope/b2_rope.cpp diff --git a/src/libraries/Box2D/b2_block_allocator.h b/src/libraries/box2d/b2_block_allocator.h similarity index 100% rename from src/libraries/Box2D/b2_block_allocator.h rename to src/libraries/box2d/b2_block_allocator.h diff --git a/src/libraries/Box2D/b2_body.h b/src/libraries/box2d/b2_body.h similarity index 100% rename from src/libraries/Box2D/b2_body.h rename to src/libraries/box2d/b2_body.h diff --git a/src/libraries/Box2D/b2_broad_phase.h b/src/libraries/box2d/b2_broad_phase.h similarity index 100% rename from src/libraries/Box2D/b2_broad_phase.h rename to src/libraries/box2d/b2_broad_phase.h diff --git a/src/libraries/Box2D/b2_chain_shape.h b/src/libraries/box2d/b2_chain_shape.h similarity index 100% rename from src/libraries/Box2D/b2_chain_shape.h rename to src/libraries/box2d/b2_chain_shape.h diff --git a/src/libraries/Box2D/b2_circle_shape.h b/src/libraries/box2d/b2_circle_shape.h similarity index 100% rename from src/libraries/Box2D/b2_circle_shape.h rename to src/libraries/box2d/b2_circle_shape.h diff --git a/src/libraries/Box2D/b2_collision.h b/src/libraries/box2d/b2_collision.h similarity index 100% rename from src/libraries/Box2D/b2_collision.h rename to src/libraries/box2d/b2_collision.h diff --git a/src/libraries/Box2D/b2_contact.h b/src/libraries/box2d/b2_contact.h similarity index 100% rename from src/libraries/Box2D/b2_contact.h rename to src/libraries/box2d/b2_contact.h diff --git a/src/libraries/Box2D/b2_contact_manager.h b/src/libraries/box2d/b2_contact_manager.h similarity index 100% rename from src/libraries/Box2D/b2_contact_manager.h rename to src/libraries/box2d/b2_contact_manager.h diff --git a/src/libraries/Box2D/b2_distance.h b/src/libraries/box2d/b2_distance.h similarity index 100% rename from src/libraries/Box2D/b2_distance.h rename to src/libraries/box2d/b2_distance.h diff --git a/src/libraries/Box2D/b2_distance_joint.h b/src/libraries/box2d/b2_distance_joint.h similarity index 100% rename from src/libraries/Box2D/b2_distance_joint.h rename to src/libraries/box2d/b2_distance_joint.h diff --git a/src/libraries/Box2D/b2_draw.h b/src/libraries/box2d/b2_draw.h similarity index 100% rename from src/libraries/Box2D/b2_draw.h rename to src/libraries/box2d/b2_draw.h diff --git a/src/libraries/Box2D/b2_dynamic_tree.h b/src/libraries/box2d/b2_dynamic_tree.h similarity index 100% rename from src/libraries/Box2D/b2_dynamic_tree.h rename to src/libraries/box2d/b2_dynamic_tree.h diff --git a/src/libraries/Box2D/b2_edge_shape.h b/src/libraries/box2d/b2_edge_shape.h similarity index 100% rename from src/libraries/Box2D/b2_edge_shape.h rename to src/libraries/box2d/b2_edge_shape.h diff --git a/src/libraries/Box2D/b2_fixture.h b/src/libraries/box2d/b2_fixture.h similarity index 100% rename from src/libraries/Box2D/b2_fixture.h rename to src/libraries/box2d/b2_fixture.h diff --git a/src/libraries/Box2D/b2_friction_joint.h b/src/libraries/box2d/b2_friction_joint.h similarity index 100% rename from src/libraries/Box2D/b2_friction_joint.h rename to src/libraries/box2d/b2_friction_joint.h diff --git a/src/libraries/Box2D/b2_gear_joint.h b/src/libraries/box2d/b2_gear_joint.h similarity index 100% rename from src/libraries/Box2D/b2_gear_joint.h rename to src/libraries/box2d/b2_gear_joint.h diff --git a/src/libraries/Box2D/b2_growable_stack.h b/src/libraries/box2d/b2_growable_stack.h similarity index 100% rename from src/libraries/Box2D/b2_growable_stack.h rename to src/libraries/box2d/b2_growable_stack.h diff --git a/src/libraries/Box2D/b2_joint.h b/src/libraries/box2d/b2_joint.h similarity index 100% rename from src/libraries/Box2D/b2_joint.h rename to src/libraries/box2d/b2_joint.h diff --git a/src/libraries/Box2D/b2_math.h b/src/libraries/box2d/b2_math.h similarity index 100% rename from src/libraries/Box2D/b2_math.h rename to src/libraries/box2d/b2_math.h diff --git a/src/libraries/Box2D/b2_motor_joint.h b/src/libraries/box2d/b2_motor_joint.h similarity index 100% rename from src/libraries/Box2D/b2_motor_joint.h rename to src/libraries/box2d/b2_motor_joint.h diff --git a/src/libraries/Box2D/b2_mouse_joint.h b/src/libraries/box2d/b2_mouse_joint.h similarity index 100% rename from src/libraries/Box2D/b2_mouse_joint.h rename to src/libraries/box2d/b2_mouse_joint.h diff --git a/src/libraries/Box2D/b2_polygon_shape.h b/src/libraries/box2d/b2_polygon_shape.h similarity index 100% rename from src/libraries/Box2D/b2_polygon_shape.h rename to src/libraries/box2d/b2_polygon_shape.h diff --git a/src/libraries/Box2D/b2_prismatic_joint.h b/src/libraries/box2d/b2_prismatic_joint.h similarity index 100% rename from src/libraries/Box2D/b2_prismatic_joint.h rename to src/libraries/box2d/b2_prismatic_joint.h diff --git a/src/libraries/Box2D/b2_pulley_joint.h b/src/libraries/box2d/b2_pulley_joint.h similarity index 100% rename from src/libraries/Box2D/b2_pulley_joint.h rename to src/libraries/box2d/b2_pulley_joint.h diff --git a/src/libraries/Box2D/b2_revolute_joint.h b/src/libraries/box2d/b2_revolute_joint.h similarity index 100% rename from src/libraries/Box2D/b2_revolute_joint.h rename to src/libraries/box2d/b2_revolute_joint.h diff --git a/src/libraries/Box2D/b2_rope.h b/src/libraries/box2d/b2_rope.h similarity index 100% rename from src/libraries/Box2D/b2_rope.h rename to src/libraries/box2d/b2_rope.h diff --git a/src/libraries/Box2D/b2_rope_joint.h b/src/libraries/box2d/b2_rope_joint.h similarity index 100% rename from src/libraries/Box2D/b2_rope_joint.h rename to src/libraries/box2d/b2_rope_joint.h diff --git a/src/libraries/Box2D/b2_settings.h b/src/libraries/box2d/b2_settings.h similarity index 100% rename from src/libraries/Box2D/b2_settings.h rename to src/libraries/box2d/b2_settings.h diff --git a/src/libraries/Box2D/b2_shape.h b/src/libraries/box2d/b2_shape.h similarity index 100% rename from src/libraries/Box2D/b2_shape.h rename to src/libraries/box2d/b2_shape.h diff --git a/src/libraries/Box2D/b2_stack_allocator.h b/src/libraries/box2d/b2_stack_allocator.h similarity index 100% rename from src/libraries/Box2D/b2_stack_allocator.h rename to src/libraries/box2d/b2_stack_allocator.h diff --git a/src/libraries/Box2D/b2_time_of_impact.h b/src/libraries/box2d/b2_time_of_impact.h similarity index 100% rename from src/libraries/Box2D/b2_time_of_impact.h rename to src/libraries/box2d/b2_time_of_impact.h diff --git a/src/libraries/Box2D/b2_time_step.h b/src/libraries/box2d/b2_time_step.h similarity index 100% rename from src/libraries/Box2D/b2_time_step.h rename to src/libraries/box2d/b2_time_step.h diff --git a/src/libraries/Box2D/b2_timer.h b/src/libraries/box2d/b2_timer.h similarity index 100% rename from src/libraries/Box2D/b2_timer.h rename to src/libraries/box2d/b2_timer.h diff --git a/src/libraries/Box2D/b2_weld_joint.h b/src/libraries/box2d/b2_weld_joint.h similarity index 100% rename from src/libraries/Box2D/b2_weld_joint.h rename to src/libraries/box2d/b2_weld_joint.h diff --git a/src/libraries/Box2D/b2_wheel_joint.h b/src/libraries/box2d/b2_wheel_joint.h similarity index 100% rename from src/libraries/Box2D/b2_wheel_joint.h rename to src/libraries/box2d/b2_wheel_joint.h diff --git a/src/libraries/Box2D/b2_world.h b/src/libraries/box2d/b2_world.h similarity index 100% rename from src/libraries/Box2D/b2_world.h rename to src/libraries/box2d/b2_world.h diff --git a/src/libraries/Box2D/b2_world_callbacks.h b/src/libraries/box2d/b2_world_callbacks.h similarity index 100% rename from src/libraries/Box2D/b2_world_callbacks.h rename to src/libraries/box2d/b2_world_callbacks.h From b074ae8f4c6d65e3018628604e4c73f37d075101 Mon Sep 17 00:00:00 2001 From: Garrett Brown Date: Sun, 16 Aug 2020 19:39:36 -0400 Subject: [PATCH 07/57] Gotta lowercase these too --- src/modules/physics/box2d/Body.h | 2 +- src/modules/physics/box2d/Contact.h | 2 +- src/modules/physics/box2d/Fixture.h | 2 +- src/modules/physics/box2d/Joint.h | 2 +- src/modules/physics/box2d/Shape.h | 2 +- src/modules/physics/box2d/World.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/modules/physics/box2d/Body.h b/src/modules/physics/box2d/Body.h index 723da4002..a8b589524 100644 --- a/src/modules/physics/box2d/Body.h +++ b/src/modules/physics/box2d/Body.h @@ -28,7 +28,7 @@ #include "physics/Body.h" // Box2D -#include +#include namespace love { diff --git a/src/modules/physics/box2d/Contact.h b/src/modules/physics/box2d/Contact.h index 2bac138a1..61df9eeeb 100644 --- a/src/modules/physics/box2d/Contact.h +++ b/src/modules/physics/box2d/Contact.h @@ -27,7 +27,7 @@ #include "World.h" // Box2D -#include +#include namespace love { diff --git a/src/modules/physics/box2d/Fixture.h b/src/modules/physics/box2d/Fixture.h index 27eb8c190..7be62df1c 100644 --- a/src/modules/physics/box2d/Fixture.h +++ b/src/modules/physics/box2d/Fixture.h @@ -29,7 +29,7 @@ #include "common/Reference.h" // Box2D -#include +#include namespace love { diff --git a/src/modules/physics/box2d/Joint.h b/src/modules/physics/box2d/Joint.h index 31ebdbe79..c8a0cbfec 100644 --- a/src/modules/physics/box2d/Joint.h +++ b/src/modules/physics/box2d/Joint.h @@ -26,7 +26,7 @@ #include "physics/Joint.h" // Box2D -#include +#include namespace love { diff --git a/src/modules/physics/box2d/Shape.h b/src/modules/physics/box2d/Shape.h index ada6b81df..5ea5903db 100644 --- a/src/modules/physics/box2d/Shape.h +++ b/src/modules/physics/box2d/Shape.h @@ -26,7 +26,7 @@ #include "physics/box2d/Body.h" // Box2D -#include +#include namespace love { diff --git a/src/modules/physics/box2d/World.h b/src/modules/physics/box2d/World.h index ea5ce3186..a95ab5353 100644 --- a/src/modules/physics/box2d/World.h +++ b/src/modules/physics/box2d/World.h @@ -31,7 +31,7 @@ #include // Box2D -#include +#include namespace love { From be5ad1f4454626d3c527ea9dd6d5de72c90df8e4 Mon Sep 17 00:00:00 2001 From: Garrett Brown Date: Sun, 16 Aug 2020 20:57:20 -0400 Subject: [PATCH 08/57] Fix isfinite erroring --- src/libraries/box2d/b2_math.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/box2d/b2_math.h b/src/libraries/box2d/b2_math.h index afe421ba8..f3042ec22 100644 --- a/src/libraries/box2d/b2_math.h +++ b/src/libraries/box2d/b2_math.h @@ -24,12 +24,12 @@ #define B2_MATH_H #include "b2_settings.h" -#include +#include /// This function is used to ensure that a floating point number is not a NaN or infinity. inline bool b2IsValid(float x) { - return isfinite(x); + return std::isfinite(x); } #define b2Sqrt(x) sqrtf(x) From 10002c91dbce887d9ce61708552e1223c69be45a Mon Sep 17 00:00:00 2001 From: Garrett Brown Date: Sun, 16 Aug 2020 21:20:16 -0400 Subject: [PATCH 09/57] Didn't mean to change these --- src/modules/physics/box2d/wrap_DistanceJoint.cpp | 8 ++++---- src/modules/physics/box2d/wrap_MouseJoint.cpp | 8 ++++---- src/modules/physics/box2d/wrap_WeldJoint.cpp | 8 ++++---- src/modules/physics/box2d/wrap_WheelJoint.cpp | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/modules/physics/box2d/wrap_DistanceJoint.cpp b/src/modules/physics/box2d/wrap_DistanceJoint.cpp index 1885d2d04..242e555b2 100644 --- a/src/modules/physics/box2d/wrap_DistanceJoint.cpp +++ b/src/modules/physics/box2d/wrap_DistanceJoint.cpp @@ -50,7 +50,7 @@ int w_DistanceJoint_getLength(lua_State *L) return 1; } -int w_DistanceJoint_setStiffness(lua_State *L) +int w_DistanceJoint_setFrequency(lua_State *L) { DistanceJoint *t = luax_checkdistancejoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); @@ -58,7 +58,7 @@ int w_DistanceJoint_setStiffness(lua_State *L) return 0; } -int w_DistanceJoint_getStiffness(lua_State *L) +int w_DistanceJoint_getFrequency(lua_State *L) { DistanceJoint *t = luax_checkdistancejoint(L, 1); lua_pushnumber(L, t->getStiffness()); @@ -84,8 +84,8 @@ static const luaL_Reg w_DistanceJoint_functions[] = { { "setLength", w_DistanceJoint_setLength }, { "getLength", w_DistanceJoint_getLength }, - { "setStiffness", w_DistanceJoint_setStiffness }, - { "getStiffness", w_DistanceJoint_getStiffness }, + { "setFrequency", w_DistanceJoint_setFrequency }, + { "getFrequency", w_DistanceJoint_getFrequency }, { "setDampingRatio", w_DistanceJoint_setDampingRatio }, { "getDampingRatio", w_DistanceJoint_getDampingRatio }, { 0, 0 } diff --git a/src/modules/physics/box2d/wrap_MouseJoint.cpp b/src/modules/physics/box2d/wrap_MouseJoint.cpp index 0e9a3b333..f30e7c9f4 100644 --- a/src/modules/physics/box2d/wrap_MouseJoint.cpp +++ b/src/modules/physics/box2d/wrap_MouseJoint.cpp @@ -66,7 +66,7 @@ int w_MouseJoint_getMaxForce(lua_State *L) return 1; } -int w_MouseJoint_setStiffness(lua_State *L) +int w_MouseJoint_setFrequency(lua_State *L) { MouseJoint *t = luax_checkmousejoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); @@ -74,7 +74,7 @@ int w_MouseJoint_setStiffness(lua_State *L) return 0; } -int w_MouseJoint_getStiffness(lua_State *L) +int w_MouseJoint_getFrequency(lua_State *L) { MouseJoint *t = luax_checkmousejoint(L, 1); lua_pushnumber(L, t->getStiffness()); @@ -102,8 +102,8 @@ static const luaL_Reg w_MouseJoint_functions[] = { "getTarget", w_MouseJoint_getTarget }, { "setMaxForce", w_MouseJoint_setMaxForce }, { "getMaxForce", w_MouseJoint_getMaxForce }, - { "setStiffness", w_MouseJoint_setStiffness }, - { "getStiffness", w_MouseJoint_getStiffness }, + { "setFrequency", w_MouseJoint_setFrequency }, + { "getFrequency", w_MouseJoint_getFrequency }, { "setDampingRatio", w_MouseJoint_setDampingRatio }, { "getDampingRatio", w_MouseJoint_getDampingRatio }, { 0, 0 } diff --git a/src/modules/physics/box2d/wrap_WeldJoint.cpp b/src/modules/physics/box2d/wrap_WeldJoint.cpp index 123e36e37..e1e960159 100644 --- a/src/modules/physics/box2d/wrap_WeldJoint.cpp +++ b/src/modules/physics/box2d/wrap_WeldJoint.cpp @@ -35,7 +35,7 @@ WeldJoint *luax_checkweldjoint(lua_State *L, int idx) return j; } -int w_WeldJoint_setStiffness(lua_State *L) +int w_WeldJoint_setFrequency(lua_State *L) { WeldJoint *t = luax_checkweldjoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); @@ -43,7 +43,7 @@ int w_WeldJoint_setStiffness(lua_State *L) return 0; } -int w_WeldJoint_getStiffness(lua_State *L) +int w_WeldJoint_getFrequency(lua_State *L) { WeldJoint *t = luax_checkweldjoint(L, 1); lua_pushnumber(L, t->getStiffness()); @@ -74,8 +74,8 @@ int w_WeldJoint_getReferenceAngle(lua_State *L) static const luaL_Reg w_WeldJoint_functions[] = { - { "setStiffness", w_WeldJoint_setStiffness }, - { "getStiffness", w_WeldJoint_getStiffness }, + { "setFrequency", w_WeldJoint_setFrequency }, + { "getFrequency", w_WeldJoint_getFrequency }, { "setDampingRatio", w_WeldJoint_setDampingRatio }, { "getDampingRatio", w_WeldJoint_getDampingRatio }, { "getReferenceAngle", w_WeldJoint_getReferenceAngle }, diff --git a/src/modules/physics/box2d/wrap_WheelJoint.cpp b/src/modules/physics/box2d/wrap_WheelJoint.cpp index 1ea4e9549..021fb675a 100644 --- a/src/modules/physics/box2d/wrap_WheelJoint.cpp +++ b/src/modules/physics/box2d/wrap_WheelJoint.cpp @@ -102,7 +102,7 @@ int w_WheelJoint_getMotorTorque(lua_State *L) return 1; } -int w_WheelJoint_setSpringStiffness(lua_State *L) +int w_WheelJoint_setSpringFrequency(lua_State *L) { WheelJoint *t = luax_checkwheeljoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); @@ -110,7 +110,7 @@ int w_WheelJoint_setSpringStiffness(lua_State *L) return 0; } -int w_WheelJoint_getSpringStiffness(lua_State *L) +int w_WheelJoint_getSpringFrequency(lua_State *L) { WheelJoint *t = luax_checkwheeljoint(L, 1); lua_pushnumber(L, t->getStiffness()); @@ -150,8 +150,8 @@ static const luaL_Reg w_WheelJoint_functions[] = { "setMaxMotorTorque", w_WheelJoint_setMaxMotorTorque }, { "getMaxMotorTorque", w_WheelJoint_getMaxMotorTorque }, { "getMotorTorque", w_WheelJoint_getMotorTorque }, - { "setSpringStiffness", w_WheelJoint_setSpringStiffness }, - { "getSpringStiffness", w_WheelJoint_getSpringStiffness }, + { "setSpringFrequency", w_WheelJoint_setSpringFrequency }, + { "getSpringFrequency", w_WheelJoint_getSpringFrequency }, { "setSpringDampingRatio", w_WheelJoint_setSpringDampingRatio }, { "getSpringDampingRatio", w_WheelJoint_getSpringDampingRatio }, { "getAxis", w_WheelJoint_getAxis }, From ed257083c39e2bc89aa86dc08df30409eece9a9c Mon Sep 17 00:00:00 2001 From: Garrett Brown Date: Sun, 16 Aug 2020 22:42:29 -0400 Subject: [PATCH 10/57] Revert this whitespace change --- src/modules/physics/box2d/Physics.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/physics/box2d/Physics.cpp b/src/modules/physics/box2d/Physics.cpp index c47bdc517..5d87fbe4a 100644 --- a/src/modules/physics/box2d/Physics.cpp +++ b/src/modules/physics/box2d/Physics.cpp @@ -305,8 +305,8 @@ Fixture *Physics::newFixture(Body *body, Shape *shape, float density) int Physics::getDistance(lua_State *L) { - Fixture* fixtureA = luax_checktype(L, 1); - Fixture* fixtureB = luax_checktype(L, 2); + Fixture *fixtureA = luax_checktype(L, 1); + Fixture *fixtureB = luax_checktype(L, 2); b2DistanceProxy pA, pB; b2DistanceInput i; b2DistanceOutput o; @@ -322,7 +322,7 @@ int Physics::getDistance(lua_State *L) i.transformB = fixtureB->fixture->GetBody()->GetTransform(); i.useRadii = true; b2Distance(&o, &c, &i); - }); + }); lua_pushnumber(L, Physics::scaleUp(o.distance)); lua_pushnumber(L, Physics::scaleUp(o.pointA.x)); From 2d6efd8b8d37e6485875614abf98f653d4576b11 Mon Sep 17 00:00:00 2001 From: Garrett Brown Date: Tue, 18 Aug 2020 00:19:37 -0400 Subject: [PATCH 11/57] Update mk file --- Android.mk | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Android.mk b/Android.mk index b8ca52504..ec867bad5 100644 --- a/Android.mk +++ b/Android.mk @@ -67,14 +67,11 @@ LOCAL_SRC_FILES := \ $(wildcard ${LOCAL_PATH}/src/modules/window/*.cpp) \ $(wildcard ${LOCAL_PATH}/src/modules/window/sdl/*.cpp) \ $(wildcard ${LOCAL_PATH}/src/libraries/ddsparse/*.cpp) \ - $(wildcard ${LOCAL_PATH}/src/libraries/Box2D/*.cpp) \ - $(wildcard ${LOCAL_PATH}/src/libraries/Box2D/Collision/*.cpp) \ - $(wildcard ${LOCAL_PATH}/src/libraries/Box2D/Collision/Shapes/*.cpp) \ - $(wildcard ${LOCAL_PATH}/src/libraries/Box2D/Common/*.cpp) \ - $(wildcard ${LOCAL_PATH}/src/libraries/Box2D/Dynamics/*.cpp) \ - $(wildcard ${LOCAL_PATH}/src/libraries/Box2D/Dynamics/Contacts/*.cpp) \ - $(wildcard ${LOCAL_PATH}/src/libraries/Box2D/Dynamics/Joints/*.cpp) \ - $(wildcard ${LOCAL_PATH}/src/libraries/Box2D/Rope/*.cpp) \ + $(wildcard ${LOCAL_PATH}/src/libraries/box2d/*.cpp) \ + $(wildcard ${LOCAL_PATH}/src/libraries/box2d/Collision/*.cpp) \ + $(wildcard ${LOCAL_PATH}/src/libraries/box2d/Common/*.cpp) \ + $(wildcard ${LOCAL_PATH}/src/libraries/box2d/Dynamics/*.cpp) \ + $(wildcard ${LOCAL_PATH}/src/libraries/box2d/Rope/*.cpp) \ $(wildcard ${LOCAL_PATH}/src/libraries/glad/*.cpp) \ $(wildcard ${LOCAL_PATH}/src/libraries/glslang/glslang/GenericCodeGen/*.cpp) \ $(wildcard ${LOCAL_PATH}/src/libraries/glslang/glslang/MachineIndependent/*.cpp) \ From a16640c89c00aa166b7acc092b5fcdf2b5256182 Mon Sep 17 00:00:00 2001 From: Garrett Brown Date: Sun, 23 Aug 2020 02:38:52 -0400 Subject: [PATCH 12/57] Added backwards compatible frequency/dampingRatio functions. Added new stiffness/damping functions. --- src/modules/physics/box2d/DistanceJoint.cpp | 32 +++++++++- src/modules/physics/box2d/DistanceJoint.h | 34 ++++++++--- src/modules/physics/box2d/MouseJoint.cpp | 38 +++++++++++- src/modules/physics/box2d/MouseJoint.h | 34 ++++++++--- src/modules/physics/box2d/Physics.cpp | 60 +++++++++++++++++++ src/modules/physics/box2d/Physics.h | 24 +++++++- src/modules/physics/box2d/WeldJoint.cpp | 32 +++++++++- src/modules/physics/box2d/WeldJoint.h | 34 ++++++++--- src/modules/physics/box2d/WheelJoint.cpp | 32 +++++++++- src/modules/physics/box2d/WheelJoint.h | 31 ++++++++-- .../physics/box2d/wrap_DistanceJoint.cpp | 40 ++++++++++++- src/modules/physics/box2d/wrap_MouseJoint.cpp | 40 ++++++++++++- src/modules/physics/box2d/wrap_WeldJoint.cpp | 40 ++++++++++++- src/modules/physics/box2d/wrap_WheelJoint.cpp | 58 +++++++++++++++--- 14 files changed, 473 insertions(+), 56 deletions(-) diff --git a/src/modules/physics/box2d/DistanceJoint.cpp b/src/modules/physics/box2d/DistanceJoint.cpp index ffe80a8d6..892ff34fd 100644 --- a/src/modules/physics/box2d/DistanceJoint.cpp +++ b/src/modules/physics/box2d/DistanceJoint.cpp @@ -56,9 +56,37 @@ float DistanceJoint::getLength() const return Physics::scaleUp(joint->GetLength()); } -void DistanceJoint::setStiffness(float hz) +void DistanceJoint::setFrequency(float hz) { - joint->SetStiffness(hz); + float stiffness, damping; + b2LinearStiffness(stiffness, damping, hz, getDampingRatio(), joint->GetBodyA(), joint->GetBodyB()); + joint->SetStiffness(stiffness); +} + +float DistanceJoint::getFrequency() const +{ + float frequency, ratio; + Physics::b2LinearFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB()); + return frequency; +} + +void DistanceJoint::setDampingRatio(float ratio) +{ + float stiffness, damping; + b2LinearStiffness(stiffness, damping, getFrequency(), ratio, joint->GetBodyA(), joint->GetBodyB()); + joint->SetDamping(damping); +} + +float DistanceJoint::getDampingRatio() const +{ + float frequency, ratio; + Physics::b2LinearFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB()); + return ratio; +} + +void DistanceJoint::setStiffness(float k) +{ + joint->SetStiffness(k); } float DistanceJoint::getStiffness() const diff --git a/src/modules/physics/box2d/DistanceJoint.h b/src/modules/physics/box2d/DistanceJoint.h index 3ca572525..45cb0a613 100644 --- a/src/modules/physics/box2d/DistanceJoint.h +++ b/src/modules/physics/box2d/DistanceJoint.h @@ -57,24 +57,42 @@ public: float getLength() const; /** - * Sets the response speed. + * Sets the response speed. Independent of mass **/ - void setStiffness(float hz); + void setFrequency(float hz); /** - * Gets the response speed. + * Gets the response speed. Independent of mass + **/ + float getFrequency() const; + + /** + * Set the spring damping ratio. Independent of mass + **/ + void setDampingRatio(float ratio); + + /** + * Get the spring damping ratio. Independent of mass + **/ + float getDampingRatio() const; + + /** + * Sets the response speed. Dependent of mass + **/ + void setStiffness(float k); + + /** + * Gets the response speed. Dependent of mass **/ float getStiffness() const; /** - * Sets the damping ratio. - * 0 = no damping, 1 = critical damping. + * Set the spring damping. Dependent of mass **/ - void setDamping(float d); + void setDamping(float ratio); /** - * Gets the damping ratio. - * 0 = no damping, 1 = critical damping. + * Get the spring damping. Dependent of mass **/ float getDamping() const; diff --git a/src/modules/physics/box2d/MouseJoint.cpp b/src/modules/physics/box2d/MouseJoint.cpp index 49f2d5f5f..4475dd53d 100644 --- a/src/modules/physics/box2d/MouseJoint.cpp +++ b/src/modules/physics/box2d/MouseJoint.cpp @@ -78,7 +78,7 @@ float MouseJoint::getMaxForce() const return Physics::scaleUp(joint->GetMaxForce()); } -void MouseJoint::setStiffness(float hz) +void MouseJoint::setFrequency(float hz) { // This is kind of a crappy check. The Stiffness is used in an internal // box2d calculation whose result must be > FLT_EPSILON, but other variables @@ -86,7 +86,41 @@ void MouseJoint::setStiffness(float hz) if (hz <= FLT_EPSILON * 2) throw love::Exception("MouseJoint Stiffness must be a positive number."); - joint->SetStiffness(hz); + float stiffness, damping; + b2LinearStiffness(stiffness, damping, hz, getDampingRatio(), joint->GetBodyA(), joint->GetBodyB()); + joint->SetStiffness(stiffness); +} + +float MouseJoint::getFrequency() const +{ + float frequency, ratio; + Physics::b2LinearFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB()); + return frequency; +} + +void MouseJoint::setDampingRatio(float ratio) +{ + float stiffness, damping; + b2LinearStiffness(stiffness, damping, getFrequency(), ratio, joint->GetBodyA(), joint->GetBodyB()); + joint->SetDamping(damping); +} + +float MouseJoint::getDampingRatio() const +{ + float frequency, ratio; + Physics::b2LinearFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB()); + return ratio; +} + +void MouseJoint::setStiffness(float k) +{ + // This is kind of a crappy check. The Stiffness is used in an internal + // box2d calculation whose result must be > FLT_EPSILON, but other variables + // go into that calculation... + if (k <= FLT_EPSILON * 2) + throw love::Exception("MouseJoint Stiffness must be a positive number."); + + joint->SetStiffness(k); } float MouseJoint::getStiffness() const diff --git a/src/modules/physics/box2d/MouseJoint.h b/src/modules/physics/box2d/MouseJoint.h index 633df0282..f308d7f78 100644 --- a/src/modules/physics/box2d/MouseJoint.h +++ b/src/modules/physics/box2d/MouseJoint.h @@ -76,24 +76,42 @@ public: float getMaxForce() const; /** - * Sets the response speed. + * Sets the response speed. Independent of mass **/ - void setStiffness(float hz); + void setFrequency(float hz); /** - * Gets the response speed. + * Gets the response speed. Independent of mass + **/ + float getFrequency() const; + + /** + * Set the spring damping ratio. Independent of mass + **/ + void setDampingRatio(float ratio); + + /** + * Get the spring damping ratio. Independent of mass + **/ + float getDampingRatio() const; + + /** + * Sets the response speed. Dependent of mass + **/ + void setStiffness(float k); + + /** + * Gets the response speed. Dependent of mass **/ float getStiffness() const; /** - * Sets the damping ratio. - * 0 = no damping, 1 = critical damping. + * Set the spring damping. Dependent of mass **/ - void setDamping(float d); + void setDamping(float ratio); /** - * Gets the damping ratio. - * 0 = no damping, 1 = critical damping. + * Get the spring damping. Dependent of mass **/ float getDamping() const; diff --git a/src/modules/physics/box2d/Physics.cpp b/src/modules/physics/box2d/Physics.cpp index 5d87fbe4a..da75cbf65 100644 --- a/src/modules/physics/box2d/Physics.cpp +++ b/src/modules/physics/box2d/Physics.cpp @@ -395,6 +395,66 @@ b2AABB Physics::scaleUp(const b2AABB &aabb) return t; } +void Physics::b2LinearFrequency(float& frequency, float& ratio, float stiffness, float damping, b2Body* bodyA, b2Body* bodyB) +{ + float massA = bodyA->GetMass(); + float massB = bodyB->GetMass(); + float mass; + if (massA > 0.0f && massB > 0.0f) + { + mass = massA * massB / (massA + massB); + } + else if (massA > 0.0f) + { + mass = massA; + } + else + { + mass = massB; + } + + if (mass == 0.0f || stiffness <= 0.0f) + { + frequency = 0.0f; + ratio = 0.0f; + return; + }; + + float omega = b2Sqrt(stiffness / mass); + frequency = omega / (2.0f * b2_pi); + ratio = damping / (mass * 2.0f * omega); +} + +void Physics::b2AngularFrequency(float& frequency, float& ratio, float stiffness, float damping, b2Body* bodyA, b2Body* bodyB) +{ + float IA = bodyA->GetInertia(); + float IB = bodyB->GetInertia(); + float I; + if (IA > 0.0f && IB > 0.0f) + { + I = IA * IB / (IA + IB); + } + else if (IA > 0.0f) + { + I = IA; + } + else + { + I = IB; + } + + if (I == 0.0f || stiffness <= 0.0f) + { + frequency = 0.0f; + ratio = 0.0f; + return; + }; + + float omega = b2Sqrt(stiffness / I); + frequency = omega / (2.0f * b2_pi); + ratio = damping / (I * 2.0f * omega); +} + } // box2d } // physics } // love diff --git a/src/modules/physics/box2d/Physics.h b/src/modules/physics/box2d/Physics.h index 151fb5f86..68518f9e0 100644 --- a/src/modules/physics/box2d/Physics.h +++ b/src/modules/physics/box2d/Physics.h @@ -354,7 +354,29 @@ public: * @param aabb The unscaled input AABB. * @return The scaled AABB. **/ - static b2AABB scaleUp(const b2AABB &aabb); + static b2AABB scaleUp(const b2AABB& aabb); + + /** + * Calculates linear frequency and damping radio from stiffness and damping + * @param frequency The output frequency + * @param ratio The output damping ratio + * @param stiffness The joint stiffness + * @param damping The joint damping + * @param bodyA The bodyA of the joint + * @param bodyB The bodyB of the joint + **/ + static void b2LinearFrequency(float& frequency, float& ratio, float stiffness, float damping, b2Body* bodyA, b2Body* bodyB); + + /** + * Calculates angular frequency and damping radio from stiffness and damping + * @param frequency The output frequency + * @param ratio The output damping ratio + * @param stiffness The joint stiffness + * @param damping The joint damping + * @param bodyA The bodyA of the joint + * @param bodyB The bodyB of the joint + **/ + static void b2AngularFrequency(float& frequency, float& ratio, float stiffness, float damping, b2Body* bodyA, b2Body* bodyB); private: diff --git a/src/modules/physics/box2d/WeldJoint.cpp b/src/modules/physics/box2d/WeldJoint.cpp index df304596a..30ead28ec 100644 --- a/src/modules/physics/box2d/WeldJoint.cpp +++ b/src/modules/physics/box2d/WeldJoint.cpp @@ -66,9 +66,37 @@ void WeldJoint::init(b2WeldJointDef &def, Body *body1, Body *body2, float xA, fl def.collideConnected = collideConnected; } -void WeldJoint::setStiffness(float hz) +void WeldJoint::setFrequency(float hz) { - joint->SetStiffness(hz); + float stiffness, damping; + b2LinearStiffness(stiffness, damping, hz, getDampingRatio(), joint->GetBodyA(), joint->GetBodyB()); + joint->SetStiffness(stiffness); +} + +float WeldJoint::getFrequency() const +{ + float frequency, ratio; + Physics::b2LinearFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB()); + return frequency; +} + +void WeldJoint::setDampingRatio(float ratio) +{ + float stiffness, damping; + b2LinearStiffness(stiffness, damping, getFrequency(), ratio, joint->GetBodyA(), joint->GetBodyB()); + joint->SetDamping(damping); +} + +float WeldJoint::getDampingRatio() const +{ + float frequency, ratio; + Physics::b2LinearFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB()); + return ratio; +} + +void WeldJoint::setStiffness(float k) +{ + joint->SetStiffness(k); } float WeldJoint::getStiffness() const diff --git a/src/modules/physics/box2d/WeldJoint.h b/src/modules/physics/box2d/WeldJoint.h index d269549e3..e0bd27e68 100644 --- a/src/modules/physics/box2d/WeldJoint.h +++ b/src/modules/physics/box2d/WeldJoint.h @@ -50,24 +50,42 @@ public: virtual ~WeldJoint(); /** - * Sets the response speed. + * Sets the response speed. Independent of mass **/ - void setStiffness(float hz); + void setFrequency(float hz); /** - * Gets the response speed. + * Gets the response speed. Independent of mass + **/ + float getFrequency() const; + + /** + * Set the spring damping ratio. Independent of mass + **/ + void setDampingRatio(float ratio); + + /** + * Get the spring damping ratio. Independent of mass + **/ + float getDampingRatio() const; + + /** + * Sets the response speed. Dependent of mass + **/ + void setStiffness(float k); + + /** + * Gets the response speed. Dependent of mass **/ float getStiffness() const; /** - * Sets the damping ratio. - * 0 = no damping, 1 = critical damping. + * Set the spring damping. Dependent of mass **/ - void setDamping(float d); + void setDamping(float ratio); /** - * Gets the damping ratio. - * 0 = no damping, 1 = critical damping. + * Get the spring damping. Dependent of mass **/ float getDamping() const; diff --git a/src/modules/physics/box2d/WheelJoint.cpp b/src/modules/physics/box2d/WheelJoint.cpp index 092b6ccf8..52b61b998 100644 --- a/src/modules/physics/box2d/WheelJoint.cpp +++ b/src/modules/physics/box2d/WheelJoint.cpp @@ -95,9 +95,37 @@ float WheelJoint::getMotorTorque(float inv_dt) const return Physics::scaleUp(Physics::scaleUp(joint->GetMotorTorque(inv_dt))); } -void WheelJoint::setStiffness(float hz) +void WheelJoint::setFrequency(float hz) { - joint->SetStiffness(hz); + float stiffness, damping; + b2AngularStiffness(stiffness, damping, hz, getDampingRatio(), joint->GetBodyA(), joint->GetBodyB()); + joint->SetStiffness(stiffness); +} + +float WheelJoint::getFrequency() const +{ + float frequency, ratio; + Physics::b2AngularFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB()); + return frequency; +} + +void WheelJoint::setDampingRatio(float ratio) +{ + float stiffness, damping; + b2AngularStiffness(stiffness, damping, getFrequency(), ratio, joint->GetBodyA(), joint->GetBodyB()); + joint->SetDamping(damping); +} + +float WheelJoint::getDampingRatio() const +{ + float frequency, ratio; + Physics::b2AngularFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB()); + return ratio; +} + +void WheelJoint::setStiffness(float k) +{ + joint->SetStiffness(k); } float WheelJoint::getStiffness() const diff --git a/src/modules/physics/box2d/WheelJoint.h b/src/modules/physics/box2d/WheelJoint.h index fe2ecc4a6..453ae9608 100644 --- a/src/modules/physics/box2d/WheelJoint.h +++ b/src/modules/physics/box2d/WheelJoint.h @@ -96,23 +96,42 @@ public: float getMotorTorque(float inv_dt) const; /** - * Set the spring frequency, in hertz. Setting the frequency to 0 - * disables the spring. + * Sets the response speed. Independent of mass **/ - void setStiffness(float hz); + void setFrequency(float hz); /** - * Get the spring frequency, in hertz. + * Gets the response speed. Independent of mass + **/ + float getFrequency() const; + + /** + * Set the spring damping ratio. Independent of mass + **/ + void setDampingRatio(float ratio); + + /** + * Get the spring damping ratio. Independent of mass + **/ + float getDampingRatio() const; + + /** + * Sets the response speed. Dependent of mass + **/ + void setStiffness(float k); + + /** + * Gets the response speed. Dependent of mass **/ float getStiffness() const; /** - * Set the spring damping ratio. + * Set the spring damping. Dependent of mass **/ void setDamping(float ratio); /** - * Get the spring damping ratio. + * Get the spring damping. Dependent of mass **/ float getDamping() const; diff --git a/src/modules/physics/box2d/wrap_DistanceJoint.cpp b/src/modules/physics/box2d/wrap_DistanceJoint.cpp index 242e555b2..d49648d39 100644 --- a/src/modules/physics/box2d/wrap_DistanceJoint.cpp +++ b/src/modules/physics/box2d/wrap_DistanceJoint.cpp @@ -54,14 +54,14 @@ int w_DistanceJoint_setFrequency(lua_State *L) { DistanceJoint *t = luax_checkdistancejoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setStiffness(arg1); + t->setFrequency(arg1); return 0; } int w_DistanceJoint_getFrequency(lua_State *L) { DistanceJoint *t = luax_checkdistancejoint(L, 1); - lua_pushnumber(L, t->getStiffness()); + lua_pushnumber(L, t->getFrequency()); return 1; } @@ -69,11 +69,41 @@ int w_DistanceJoint_setDampingRatio(lua_State *L) { DistanceJoint *t = luax_checkdistancejoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setDamping(arg1); + t->setDampingRatio(arg1); return 0; } int w_DistanceJoint_getDampingRatio(lua_State *L) +{ + DistanceJoint *t = luax_checkdistancejoint(L, 1); + lua_pushnumber(L, t->getDampingRatio()); + return 1; +} + +int w_DistanceJoint_setStiffness(lua_State *L) +{ + DistanceJoint *t = luax_checkdistancejoint(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + t->setStiffness(arg1); + return 0; +} + +int w_DistanceJoint_getStiffness(lua_State *L) +{ + DistanceJoint *t = luax_checkdistancejoint(L, 1); + lua_pushnumber(L, t->getStiffness()); + return 1; +} + +int w_DistanceJoint_setDamping(lua_State *L) +{ + DistanceJoint *t = luax_checkdistancejoint(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + t->setDamping(arg1); + return 0; +} + +int w_DistanceJoint_getDamping(lua_State *L) { DistanceJoint *t = luax_checkdistancejoint(L, 1); lua_pushnumber(L, t->getDamping()); @@ -88,6 +118,10 @@ static const luaL_Reg w_DistanceJoint_functions[] = { "getFrequency", w_DistanceJoint_getFrequency }, { "setDampingRatio", w_DistanceJoint_setDampingRatio }, { "getDampingRatio", w_DistanceJoint_getDampingRatio }, + { "setStiffness", w_DistanceJoint_setStiffness }, + { "getStiffness", w_DistanceJoint_getStiffness }, + { "setDamping", w_DistanceJoint_setDamping }, + { "getDamping", w_DistanceJoint_getDamping }, { 0, 0 } }; diff --git a/src/modules/physics/box2d/wrap_MouseJoint.cpp b/src/modules/physics/box2d/wrap_MouseJoint.cpp index f30e7c9f4..e6bce8307 100644 --- a/src/modules/physics/box2d/wrap_MouseJoint.cpp +++ b/src/modules/physics/box2d/wrap_MouseJoint.cpp @@ -70,14 +70,14 @@ int w_MouseJoint_setFrequency(lua_State *L) { MouseJoint *t = luax_checkmousejoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - luax_catchexcept(L, [&]() { t->setStiffness(arg1); }); + luax_catchexcept(L, [&]() { t->setFrequency(arg1); }); return 0; } int w_MouseJoint_getFrequency(lua_State *L) { MouseJoint *t = luax_checkmousejoint(L, 1); - lua_pushnumber(L, t->getStiffness()); + lua_pushnumber(L, t->getFrequency()); return 1; } @@ -85,11 +85,41 @@ int w_MouseJoint_setDampingRatio(lua_State *L) { MouseJoint *t = luax_checkmousejoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setDamping(arg1); + t->setDampingRatio(arg1); return 0; } int w_MouseJoint_getDampingRatio(lua_State *L) +{ + MouseJoint *t = luax_checkmousejoint(L, 1); + lua_pushnumber(L, t->getDampingRatio()); + return 1; +} + +int w_MouseJoint_setStiffness(lua_State *L) +{ + MouseJoint *t = luax_checkmousejoint(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + luax_catchexcept(L, [&]() { t->setStiffness(arg1); }); + return 0; +} + +int w_MouseJoint_getStiffness(lua_State *L) +{ + MouseJoint *t = luax_checkmousejoint(L, 1); + lua_pushnumber(L, t->getStiffness()); + return 1; +} + +int w_MouseJoint_setDamping(lua_State *L) +{ + MouseJoint *t = luax_checkmousejoint(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + t->setDamping(arg1); + return 0; +} + +int w_MouseJoint_getDamping(lua_State *L) { MouseJoint *t = luax_checkmousejoint(L, 1); lua_pushnumber(L, t->getDamping()); @@ -106,6 +136,10 @@ static const luaL_Reg w_MouseJoint_functions[] = { "getFrequency", w_MouseJoint_getFrequency }, { "setDampingRatio", w_MouseJoint_setDampingRatio }, { "getDampingRatio", w_MouseJoint_getDampingRatio }, + { "setStiffness", w_MouseJoint_setStiffness }, + { "getStiffness", w_MouseJoint_getStiffness }, + { "setDamping", w_MouseJoint_setDamping }, + { "getDamping", w_MouseJoint_getDamping }, { 0, 0 } }; diff --git a/src/modules/physics/box2d/wrap_WeldJoint.cpp b/src/modules/physics/box2d/wrap_WeldJoint.cpp index e1e960159..7d1efc020 100644 --- a/src/modules/physics/box2d/wrap_WeldJoint.cpp +++ b/src/modules/physics/box2d/wrap_WeldJoint.cpp @@ -39,14 +39,14 @@ int w_WeldJoint_setFrequency(lua_State *L) { WeldJoint *t = luax_checkweldjoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setStiffness(arg1); + t->setFrequency(arg1); return 0; } int w_WeldJoint_getFrequency(lua_State *L) { WeldJoint *t = luax_checkweldjoint(L, 1); - lua_pushnumber(L, t->getStiffness()); + lua_pushnumber(L, t->getFrequency()); return 1; } @@ -54,11 +54,41 @@ int w_WeldJoint_setDampingRatio(lua_State *L) { WeldJoint *t = luax_checkweldjoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setDamping(arg1); + t->setDampingRatio(arg1); return 0; } int w_WeldJoint_getDampingRatio(lua_State *L) +{ + WeldJoint *t = luax_checkweldjoint(L, 1); + lua_pushnumber(L, t->getDampingRatio()); + return 1; +} + +int w_WeldJoint_setStiffness(lua_State *L) +{ + WeldJoint *t = luax_checkweldjoint(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + t->setStiffness(arg1); + return 0; +} + +int w_WeldJoint_getStiffness(lua_State *L) +{ + WeldJoint *t = luax_checkweldjoint(L, 1); + lua_pushnumber(L, t->getStiffness()); + return 1; +} + +int w_WeldJoint_setDamping(lua_State *L) +{ + WeldJoint *t = luax_checkweldjoint(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + t->setDamping(arg1); + return 0; +} + +int w_WeldJoint_getDamping(lua_State *L) { WeldJoint *t = luax_checkweldjoint(L, 1); lua_pushnumber(L, t->getDamping()); @@ -78,6 +108,10 @@ static const luaL_Reg w_WeldJoint_functions[] = { "getFrequency", w_WeldJoint_getFrequency }, { "setDampingRatio", w_WeldJoint_setDampingRatio }, { "getDampingRatio", w_WeldJoint_getDampingRatio }, + { "setStiffness", w_WeldJoint_setStiffness }, + { "getStiffness", w_WeldJoint_getStiffness }, + { "setDamping", w_WeldJoint_setDamping }, + { "getDamping", w_WeldJoint_getDamping }, { "getReferenceAngle", w_WeldJoint_getReferenceAngle }, { 0, 0 } }; diff --git a/src/modules/physics/box2d/wrap_WheelJoint.cpp b/src/modules/physics/box2d/wrap_WheelJoint.cpp index 021fb675a..3f2a8e5b6 100644 --- a/src/modules/physics/box2d/wrap_WheelJoint.cpp +++ b/src/modules/physics/box2d/wrap_WheelJoint.cpp @@ -102,7 +102,37 @@ int w_WheelJoint_getMotorTorque(lua_State *L) return 1; } -int w_WheelJoint_setSpringFrequency(lua_State *L) +int w_WheelJoint_setFrequency(lua_State *L) +{ + WheelJoint *t = luax_checkwheeljoint(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + t->setFrequency(arg1); + return 0; +} + +int w_WheelJoint_getFrequency(lua_State *L) +{ + WheelJoint *t = luax_checkwheeljoint(L, 1); + lua_pushnumber(L, t->getFrequency()); + return 1; +} + +int w_WheelJoint_setDampingRatio(lua_State *L) +{ + WheelJoint *t = luax_checkwheeljoint(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + t->setDampingRatio(arg1); + return 0; +} + +int w_WheelJoint_getDampingRatio(lua_State *L) +{ + WheelJoint *t = luax_checkwheeljoint(L, 1); + lua_pushnumber(L, t->getDampingRatio()); + return 1; +} + +int w_WheelJoint_setStiffness(lua_State *L) { WheelJoint *t = luax_checkwheeljoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); @@ -110,14 +140,14 @@ int w_WheelJoint_setSpringFrequency(lua_State *L) return 0; } -int w_WheelJoint_getSpringFrequency(lua_State *L) +int w_WheelJoint_getStiffness(lua_State *L) { WheelJoint *t = luax_checkwheeljoint(L, 1); lua_pushnumber(L, t->getStiffness()); return 1; } -int w_WheelJoint_setSpringDampingRatio(lua_State *L) +int w_WheelJoint_setDamping(lua_State *L) { WheelJoint *t = luax_checkwheeljoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); @@ -125,7 +155,7 @@ int w_WheelJoint_setSpringDampingRatio(lua_State *L) return 0; } -int w_WheelJoint_getSpringDampingRatio(lua_State *L) +int w_WheelJoint_getDamping(lua_State *L) { WheelJoint *t = luax_checkwheeljoint(L, 1); lua_pushnumber(L, t->getDamping()); @@ -150,10 +180,22 @@ static const luaL_Reg w_WheelJoint_functions[] = { "setMaxMotorTorque", w_WheelJoint_setMaxMotorTorque }, { "getMaxMotorTorque", w_WheelJoint_getMaxMotorTorque }, { "getMotorTorque", w_WheelJoint_getMotorTorque }, - { "setSpringFrequency", w_WheelJoint_setSpringFrequency }, - { "getSpringFrequency", w_WheelJoint_getSpringFrequency }, - { "setSpringDampingRatio", w_WheelJoint_setSpringDampingRatio }, - { "getSpringDampingRatio", w_WheelJoint_getSpringDampingRatio }, + { "setSpringFrequency", w_WheelJoint_setFrequency }, + { "getSpringFrequency", w_WheelJoint_getFrequency }, + { "setSpringDampingRatio", w_WheelJoint_setDampingRatio }, + { "getSpringDampingRatio", w_WheelJoint_getDampingRatio }, + { "setSpringStiffness", w_WheelJoint_setStiffness }, + { "getSpringStiffness", w_WheelJoint_getStiffness }, + { "setSpringDamping", w_WheelJoint_setDamping }, + { "getSpringDamping", w_WheelJoint_getDamping }, + { "setFrequency", w_WheelJoint_setFrequency }, + { "getFrequency", w_WheelJoint_getFrequency }, + { "setDampingRatio", w_WheelJoint_setDampingRatio }, + { "getDampingRatio", w_WheelJoint_getDampingRatio }, + { "setStiffness", w_WheelJoint_setStiffness }, + { "getStiffness", w_WheelJoint_getStiffness }, + { "setDamping", w_WheelJoint_setDamping }, + { "getDamping", w_WheelJoint_getDamping }, { "getAxis", w_WheelJoint_getAxis }, { 0, 0 } }; From 228e0b9df1c89197a0c1f09de27a2dd4e6b37c5d Mon Sep 17 00:00:00 2001 From: Garrett Brown Date: Wed, 16 Sep 2020 21:47:58 -0400 Subject: [PATCH 13/57] Fix casing here? --- platform/unix/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/unix/configure.ac b/platform/unix/configure.ac index 84a4b0dd1..e431f5744 100644 --- a/platform/unix/configure.ac +++ b/platform/unix/configure.ac @@ -81,7 +81,7 @@ AC_ARG_ENABLE([library-lua53], [ --disable-library-lua53 Turn off library lu # Select the libraries we need to build, based on the selected modules AS_VAR_IF([enable_module_filesystem], [yes], [enable_library_physfs=yes], [enable_library_physfs=no]) -AS_VAR_IF([enable_module_physics], [yes], [enable_library_Box2D=yes], [enable_library_Box2D=no]) +AS_VAR_IF([enable_module_physics], [yes], [enable_library_box2d=yes], [enable_library_box2d=no]) AS_VAR_IF([enable_module_image], [yes], [enable_library_ddsparse=yes], [enable_library_ddsparse=no]) AS_VAR_IF([enable_module_graphics], [yes], [enable_library_glad=yes], [enable_library_glad=no]) AS_VAR_IF([enable_module_graphics], [yes], [enable_library_glslang=yes], [enable_library_glslang=no]) From bd4f2567358c462b637c489b7c6dfc0e08760b02 Mon Sep 17 00:00:00 2001 From: Garrett Brown Date: Thu, 17 Sep 2020 09:37:23 -0400 Subject: [PATCH 14/57] Lower case folders --- src/libraries/box2d/{Collision => collision}/b2_broad_phase.cpp | 0 src/libraries/box2d/{Collision => collision}/b2_chain_shape.cpp | 0 src/libraries/box2d/{Collision => collision}/b2_circle_shape.cpp | 0 .../box2d/{Collision => collision}/b2_collide_circle.cpp | 0 src/libraries/box2d/{Collision => collision}/b2_collide_edge.cpp | 0 .../box2d/{Collision => collision}/b2_collide_polygon.cpp | 0 src/libraries/box2d/{Collision => collision}/b2_collision.cpp | 0 src/libraries/box2d/{Collision => collision}/b2_distance.cpp | 0 src/libraries/box2d/{Collision => collision}/b2_dynamic_tree.cpp | 0 src/libraries/box2d/{Collision => collision}/b2_edge_shape.cpp | 0 src/libraries/box2d/{Collision => collision}/b2_polygon_shape.cpp | 0 .../box2d/{Collision => collision}/b2_time_of_impact.cpp | 0 src/libraries/box2d/{Common => common}/b2_block_allocator.cpp | 0 src/libraries/box2d/{Common => common}/b2_draw.cpp | 0 src/libraries/box2d/{Common => common}/b2_math.cpp | 0 src/libraries/box2d/{Common => common}/b2_settings.cpp | 0 src/libraries/box2d/{Common => common}/b2_stack_allocator.cpp | 0 src/libraries/box2d/{Common => common}/b2_timer.cpp | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_body.cpp | 0 .../box2d/{Dynamics => dynamics}/b2_chain_circle_contact.cpp | 0 .../box2d/{Dynamics => dynamics}/b2_chain_circle_contact.h | 0 .../box2d/{Dynamics => dynamics}/b2_chain_polygon_contact.cpp | 0 .../box2d/{Dynamics => dynamics}/b2_chain_polygon_contact.h | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_circle_contact.cpp | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_circle_contact.h | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_contact.cpp | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_contact_manager.cpp | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_contact_solver.cpp | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_contact_solver.h | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_distance_joint.cpp | 0 .../box2d/{Dynamics => dynamics}/b2_edge_circle_contact.cpp | 0 .../box2d/{Dynamics => dynamics}/b2_edge_circle_contact.h | 0 .../box2d/{Dynamics => dynamics}/b2_edge_polygon_contact.cpp | 0 .../box2d/{Dynamics => dynamics}/b2_edge_polygon_contact.h | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_fixture.cpp | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_friction_joint.cpp | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_gear_joint.cpp | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_island.cpp | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_island.h | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_joint.cpp | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_motor_joint.cpp | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_mouse_joint.cpp | 0 .../box2d/{Dynamics => dynamics}/b2_polygon_circle_contact.cpp | 0 .../box2d/{Dynamics => dynamics}/b2_polygon_circle_contact.h | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_polygon_contact.cpp | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_polygon_contact.h | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_prismatic_joint.cpp | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_pulley_joint.cpp | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_revolute_joint.cpp | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_rope_joint.cpp | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_weld_joint.cpp | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_wheel_joint.cpp | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_world.cpp | 0 src/libraries/box2d/{Dynamics => dynamics}/b2_world_callbacks.cpp | 0 src/libraries/box2d/{Rope => rope}/b2_rope.cpp | 0 55 files changed, 0 insertions(+), 0 deletions(-) rename src/libraries/box2d/{Collision => collision}/b2_broad_phase.cpp (100%) rename src/libraries/box2d/{Collision => collision}/b2_chain_shape.cpp (100%) rename src/libraries/box2d/{Collision => collision}/b2_circle_shape.cpp (100%) rename src/libraries/box2d/{Collision => collision}/b2_collide_circle.cpp (100%) rename src/libraries/box2d/{Collision => collision}/b2_collide_edge.cpp (100%) rename src/libraries/box2d/{Collision => collision}/b2_collide_polygon.cpp (100%) rename src/libraries/box2d/{Collision => collision}/b2_collision.cpp (100%) rename src/libraries/box2d/{Collision => collision}/b2_distance.cpp (100%) rename src/libraries/box2d/{Collision => collision}/b2_dynamic_tree.cpp (100%) rename src/libraries/box2d/{Collision => collision}/b2_edge_shape.cpp (100%) rename src/libraries/box2d/{Collision => collision}/b2_polygon_shape.cpp (100%) rename src/libraries/box2d/{Collision => collision}/b2_time_of_impact.cpp (100%) rename src/libraries/box2d/{Common => common}/b2_block_allocator.cpp (100%) rename src/libraries/box2d/{Common => common}/b2_draw.cpp (100%) rename src/libraries/box2d/{Common => common}/b2_math.cpp (100%) rename src/libraries/box2d/{Common => common}/b2_settings.cpp (100%) rename src/libraries/box2d/{Common => common}/b2_stack_allocator.cpp (100%) rename src/libraries/box2d/{Common => common}/b2_timer.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_body.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_chain_circle_contact.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_chain_circle_contact.h (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_chain_polygon_contact.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_chain_polygon_contact.h (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_circle_contact.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_circle_contact.h (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_contact.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_contact_manager.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_contact_solver.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_contact_solver.h (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_distance_joint.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_edge_circle_contact.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_edge_circle_contact.h (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_edge_polygon_contact.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_edge_polygon_contact.h (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_fixture.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_friction_joint.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_gear_joint.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_island.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_island.h (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_joint.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_motor_joint.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_mouse_joint.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_polygon_circle_contact.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_polygon_circle_contact.h (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_polygon_contact.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_polygon_contact.h (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_prismatic_joint.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_pulley_joint.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_revolute_joint.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_rope_joint.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_weld_joint.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_wheel_joint.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_world.cpp (100%) rename src/libraries/box2d/{Dynamics => dynamics}/b2_world_callbacks.cpp (100%) rename src/libraries/box2d/{Rope => rope}/b2_rope.cpp (100%) diff --git a/src/libraries/box2d/Collision/b2_broad_phase.cpp b/src/libraries/box2d/collision/b2_broad_phase.cpp similarity index 100% rename from src/libraries/box2d/Collision/b2_broad_phase.cpp rename to src/libraries/box2d/collision/b2_broad_phase.cpp diff --git a/src/libraries/box2d/Collision/b2_chain_shape.cpp b/src/libraries/box2d/collision/b2_chain_shape.cpp similarity index 100% rename from src/libraries/box2d/Collision/b2_chain_shape.cpp rename to src/libraries/box2d/collision/b2_chain_shape.cpp diff --git a/src/libraries/box2d/Collision/b2_circle_shape.cpp b/src/libraries/box2d/collision/b2_circle_shape.cpp similarity index 100% rename from src/libraries/box2d/Collision/b2_circle_shape.cpp rename to src/libraries/box2d/collision/b2_circle_shape.cpp diff --git a/src/libraries/box2d/Collision/b2_collide_circle.cpp b/src/libraries/box2d/collision/b2_collide_circle.cpp similarity index 100% rename from src/libraries/box2d/Collision/b2_collide_circle.cpp rename to src/libraries/box2d/collision/b2_collide_circle.cpp diff --git a/src/libraries/box2d/Collision/b2_collide_edge.cpp b/src/libraries/box2d/collision/b2_collide_edge.cpp similarity index 100% rename from src/libraries/box2d/Collision/b2_collide_edge.cpp rename to src/libraries/box2d/collision/b2_collide_edge.cpp diff --git a/src/libraries/box2d/Collision/b2_collide_polygon.cpp b/src/libraries/box2d/collision/b2_collide_polygon.cpp similarity index 100% rename from src/libraries/box2d/Collision/b2_collide_polygon.cpp rename to src/libraries/box2d/collision/b2_collide_polygon.cpp diff --git a/src/libraries/box2d/Collision/b2_collision.cpp b/src/libraries/box2d/collision/b2_collision.cpp similarity index 100% rename from src/libraries/box2d/Collision/b2_collision.cpp rename to src/libraries/box2d/collision/b2_collision.cpp diff --git a/src/libraries/box2d/Collision/b2_distance.cpp b/src/libraries/box2d/collision/b2_distance.cpp similarity index 100% rename from src/libraries/box2d/Collision/b2_distance.cpp rename to src/libraries/box2d/collision/b2_distance.cpp diff --git a/src/libraries/box2d/Collision/b2_dynamic_tree.cpp b/src/libraries/box2d/collision/b2_dynamic_tree.cpp similarity index 100% rename from src/libraries/box2d/Collision/b2_dynamic_tree.cpp rename to src/libraries/box2d/collision/b2_dynamic_tree.cpp diff --git a/src/libraries/box2d/Collision/b2_edge_shape.cpp b/src/libraries/box2d/collision/b2_edge_shape.cpp similarity index 100% rename from src/libraries/box2d/Collision/b2_edge_shape.cpp rename to src/libraries/box2d/collision/b2_edge_shape.cpp diff --git a/src/libraries/box2d/Collision/b2_polygon_shape.cpp b/src/libraries/box2d/collision/b2_polygon_shape.cpp similarity index 100% rename from src/libraries/box2d/Collision/b2_polygon_shape.cpp rename to src/libraries/box2d/collision/b2_polygon_shape.cpp diff --git a/src/libraries/box2d/Collision/b2_time_of_impact.cpp b/src/libraries/box2d/collision/b2_time_of_impact.cpp similarity index 100% rename from src/libraries/box2d/Collision/b2_time_of_impact.cpp rename to src/libraries/box2d/collision/b2_time_of_impact.cpp diff --git a/src/libraries/box2d/Common/b2_block_allocator.cpp b/src/libraries/box2d/common/b2_block_allocator.cpp similarity index 100% rename from src/libraries/box2d/Common/b2_block_allocator.cpp rename to src/libraries/box2d/common/b2_block_allocator.cpp diff --git a/src/libraries/box2d/Common/b2_draw.cpp b/src/libraries/box2d/common/b2_draw.cpp similarity index 100% rename from src/libraries/box2d/Common/b2_draw.cpp rename to src/libraries/box2d/common/b2_draw.cpp diff --git a/src/libraries/box2d/Common/b2_math.cpp b/src/libraries/box2d/common/b2_math.cpp similarity index 100% rename from src/libraries/box2d/Common/b2_math.cpp rename to src/libraries/box2d/common/b2_math.cpp diff --git a/src/libraries/box2d/Common/b2_settings.cpp b/src/libraries/box2d/common/b2_settings.cpp similarity index 100% rename from src/libraries/box2d/Common/b2_settings.cpp rename to src/libraries/box2d/common/b2_settings.cpp diff --git a/src/libraries/box2d/Common/b2_stack_allocator.cpp b/src/libraries/box2d/common/b2_stack_allocator.cpp similarity index 100% rename from src/libraries/box2d/Common/b2_stack_allocator.cpp rename to src/libraries/box2d/common/b2_stack_allocator.cpp diff --git a/src/libraries/box2d/Common/b2_timer.cpp b/src/libraries/box2d/common/b2_timer.cpp similarity index 100% rename from src/libraries/box2d/Common/b2_timer.cpp rename to src/libraries/box2d/common/b2_timer.cpp diff --git a/src/libraries/box2d/Dynamics/b2_body.cpp b/src/libraries/box2d/dynamics/b2_body.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_body.cpp rename to src/libraries/box2d/dynamics/b2_body.cpp diff --git a/src/libraries/box2d/Dynamics/b2_chain_circle_contact.cpp b/src/libraries/box2d/dynamics/b2_chain_circle_contact.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_chain_circle_contact.cpp rename to src/libraries/box2d/dynamics/b2_chain_circle_contact.cpp diff --git a/src/libraries/box2d/Dynamics/b2_chain_circle_contact.h b/src/libraries/box2d/dynamics/b2_chain_circle_contact.h similarity index 100% rename from src/libraries/box2d/Dynamics/b2_chain_circle_contact.h rename to src/libraries/box2d/dynamics/b2_chain_circle_contact.h diff --git a/src/libraries/box2d/Dynamics/b2_chain_polygon_contact.cpp b/src/libraries/box2d/dynamics/b2_chain_polygon_contact.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_chain_polygon_contact.cpp rename to src/libraries/box2d/dynamics/b2_chain_polygon_contact.cpp diff --git a/src/libraries/box2d/Dynamics/b2_chain_polygon_contact.h b/src/libraries/box2d/dynamics/b2_chain_polygon_contact.h similarity index 100% rename from src/libraries/box2d/Dynamics/b2_chain_polygon_contact.h rename to src/libraries/box2d/dynamics/b2_chain_polygon_contact.h diff --git a/src/libraries/box2d/Dynamics/b2_circle_contact.cpp b/src/libraries/box2d/dynamics/b2_circle_contact.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_circle_contact.cpp rename to src/libraries/box2d/dynamics/b2_circle_contact.cpp diff --git a/src/libraries/box2d/Dynamics/b2_circle_contact.h b/src/libraries/box2d/dynamics/b2_circle_contact.h similarity index 100% rename from src/libraries/box2d/Dynamics/b2_circle_contact.h rename to src/libraries/box2d/dynamics/b2_circle_contact.h diff --git a/src/libraries/box2d/Dynamics/b2_contact.cpp b/src/libraries/box2d/dynamics/b2_contact.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_contact.cpp rename to src/libraries/box2d/dynamics/b2_contact.cpp diff --git a/src/libraries/box2d/Dynamics/b2_contact_manager.cpp b/src/libraries/box2d/dynamics/b2_contact_manager.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_contact_manager.cpp rename to src/libraries/box2d/dynamics/b2_contact_manager.cpp diff --git a/src/libraries/box2d/Dynamics/b2_contact_solver.cpp b/src/libraries/box2d/dynamics/b2_contact_solver.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_contact_solver.cpp rename to src/libraries/box2d/dynamics/b2_contact_solver.cpp diff --git a/src/libraries/box2d/Dynamics/b2_contact_solver.h b/src/libraries/box2d/dynamics/b2_contact_solver.h similarity index 100% rename from src/libraries/box2d/Dynamics/b2_contact_solver.h rename to src/libraries/box2d/dynamics/b2_contact_solver.h diff --git a/src/libraries/box2d/Dynamics/b2_distance_joint.cpp b/src/libraries/box2d/dynamics/b2_distance_joint.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_distance_joint.cpp rename to src/libraries/box2d/dynamics/b2_distance_joint.cpp diff --git a/src/libraries/box2d/Dynamics/b2_edge_circle_contact.cpp b/src/libraries/box2d/dynamics/b2_edge_circle_contact.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_edge_circle_contact.cpp rename to src/libraries/box2d/dynamics/b2_edge_circle_contact.cpp diff --git a/src/libraries/box2d/Dynamics/b2_edge_circle_contact.h b/src/libraries/box2d/dynamics/b2_edge_circle_contact.h similarity index 100% rename from src/libraries/box2d/Dynamics/b2_edge_circle_contact.h rename to src/libraries/box2d/dynamics/b2_edge_circle_contact.h diff --git a/src/libraries/box2d/Dynamics/b2_edge_polygon_contact.cpp b/src/libraries/box2d/dynamics/b2_edge_polygon_contact.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_edge_polygon_contact.cpp rename to src/libraries/box2d/dynamics/b2_edge_polygon_contact.cpp diff --git a/src/libraries/box2d/Dynamics/b2_edge_polygon_contact.h b/src/libraries/box2d/dynamics/b2_edge_polygon_contact.h similarity index 100% rename from src/libraries/box2d/Dynamics/b2_edge_polygon_contact.h rename to src/libraries/box2d/dynamics/b2_edge_polygon_contact.h diff --git a/src/libraries/box2d/Dynamics/b2_fixture.cpp b/src/libraries/box2d/dynamics/b2_fixture.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_fixture.cpp rename to src/libraries/box2d/dynamics/b2_fixture.cpp diff --git a/src/libraries/box2d/Dynamics/b2_friction_joint.cpp b/src/libraries/box2d/dynamics/b2_friction_joint.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_friction_joint.cpp rename to src/libraries/box2d/dynamics/b2_friction_joint.cpp diff --git a/src/libraries/box2d/Dynamics/b2_gear_joint.cpp b/src/libraries/box2d/dynamics/b2_gear_joint.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_gear_joint.cpp rename to src/libraries/box2d/dynamics/b2_gear_joint.cpp diff --git a/src/libraries/box2d/Dynamics/b2_island.cpp b/src/libraries/box2d/dynamics/b2_island.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_island.cpp rename to src/libraries/box2d/dynamics/b2_island.cpp diff --git a/src/libraries/box2d/Dynamics/b2_island.h b/src/libraries/box2d/dynamics/b2_island.h similarity index 100% rename from src/libraries/box2d/Dynamics/b2_island.h rename to src/libraries/box2d/dynamics/b2_island.h diff --git a/src/libraries/box2d/Dynamics/b2_joint.cpp b/src/libraries/box2d/dynamics/b2_joint.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_joint.cpp rename to src/libraries/box2d/dynamics/b2_joint.cpp diff --git a/src/libraries/box2d/Dynamics/b2_motor_joint.cpp b/src/libraries/box2d/dynamics/b2_motor_joint.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_motor_joint.cpp rename to src/libraries/box2d/dynamics/b2_motor_joint.cpp diff --git a/src/libraries/box2d/Dynamics/b2_mouse_joint.cpp b/src/libraries/box2d/dynamics/b2_mouse_joint.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_mouse_joint.cpp rename to src/libraries/box2d/dynamics/b2_mouse_joint.cpp diff --git a/src/libraries/box2d/Dynamics/b2_polygon_circle_contact.cpp b/src/libraries/box2d/dynamics/b2_polygon_circle_contact.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_polygon_circle_contact.cpp rename to src/libraries/box2d/dynamics/b2_polygon_circle_contact.cpp diff --git a/src/libraries/box2d/Dynamics/b2_polygon_circle_contact.h b/src/libraries/box2d/dynamics/b2_polygon_circle_contact.h similarity index 100% rename from src/libraries/box2d/Dynamics/b2_polygon_circle_contact.h rename to src/libraries/box2d/dynamics/b2_polygon_circle_contact.h diff --git a/src/libraries/box2d/Dynamics/b2_polygon_contact.cpp b/src/libraries/box2d/dynamics/b2_polygon_contact.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_polygon_contact.cpp rename to src/libraries/box2d/dynamics/b2_polygon_contact.cpp diff --git a/src/libraries/box2d/Dynamics/b2_polygon_contact.h b/src/libraries/box2d/dynamics/b2_polygon_contact.h similarity index 100% rename from src/libraries/box2d/Dynamics/b2_polygon_contact.h rename to src/libraries/box2d/dynamics/b2_polygon_contact.h diff --git a/src/libraries/box2d/Dynamics/b2_prismatic_joint.cpp b/src/libraries/box2d/dynamics/b2_prismatic_joint.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_prismatic_joint.cpp rename to src/libraries/box2d/dynamics/b2_prismatic_joint.cpp diff --git a/src/libraries/box2d/Dynamics/b2_pulley_joint.cpp b/src/libraries/box2d/dynamics/b2_pulley_joint.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_pulley_joint.cpp rename to src/libraries/box2d/dynamics/b2_pulley_joint.cpp diff --git a/src/libraries/box2d/Dynamics/b2_revolute_joint.cpp b/src/libraries/box2d/dynamics/b2_revolute_joint.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_revolute_joint.cpp rename to src/libraries/box2d/dynamics/b2_revolute_joint.cpp diff --git a/src/libraries/box2d/Dynamics/b2_rope_joint.cpp b/src/libraries/box2d/dynamics/b2_rope_joint.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_rope_joint.cpp rename to src/libraries/box2d/dynamics/b2_rope_joint.cpp diff --git a/src/libraries/box2d/Dynamics/b2_weld_joint.cpp b/src/libraries/box2d/dynamics/b2_weld_joint.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_weld_joint.cpp rename to src/libraries/box2d/dynamics/b2_weld_joint.cpp diff --git a/src/libraries/box2d/Dynamics/b2_wheel_joint.cpp b/src/libraries/box2d/dynamics/b2_wheel_joint.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_wheel_joint.cpp rename to src/libraries/box2d/dynamics/b2_wheel_joint.cpp diff --git a/src/libraries/box2d/Dynamics/b2_world.cpp b/src/libraries/box2d/dynamics/b2_world.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_world.cpp rename to src/libraries/box2d/dynamics/b2_world.cpp diff --git a/src/libraries/box2d/Dynamics/b2_world_callbacks.cpp b/src/libraries/box2d/dynamics/b2_world_callbacks.cpp similarity index 100% rename from src/libraries/box2d/Dynamics/b2_world_callbacks.cpp rename to src/libraries/box2d/dynamics/b2_world_callbacks.cpp diff --git a/src/libraries/box2d/Rope/b2_rope.cpp b/src/libraries/box2d/rope/b2_rope.cpp similarity index 100% rename from src/libraries/box2d/Rope/b2_rope.cpp rename to src/libraries/box2d/rope/b2_rope.cpp From 7d24beab9080d69448dcbf3a36d029208e11cdd6 Mon Sep 17 00:00:00 2001 From: Garrett Brown Date: Thu, 17 Sep 2020 09:51:38 -0400 Subject: [PATCH 15/57] Add box2d to includes --- platform/unix/genmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/unix/genmodules b/platform/unix/genmodules index 61c81292c..78551842b 100644 --- a/platform/unix/genmodules +++ b/platform/unix/genmodules @@ -106,7 +106,7 @@ inc_modules="$inc_current/modules" inc_libraries="$inc_current/libraries" cat > src/Makefile.am << EOF -AM_CPPFLAGS = -I$inc_current -I$inc_modules -I$inc_libraries -I$inc_libraries/enet/libenet/include \$(LOVE_INCLUDES) \$(FILE_OFFSET)\ +AM_CPPFLAGS = -I$inc_current -I$inc_modules -I$inc_libraries -I$inc_libraries/enet/libenet/include -I$inc_libraries/box2d \$(LOVE_INCLUDES) \$(FILE_OFFSET)\ \$(SDL_CFLAGS) \$(lua_CFLAGS) \$(freetype2_CFLAGS)\ \$(openal_CFLAGS) \$(zlib_CFLAGS) \$(libmodplug_CFLAGS)\ \$(vorbisfile_CFLAGS) \$(theora_CFLAGS) From 5dd4a463beba7eb956f881b73f6d5572105768e3 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Tue, 29 Sep 2020 20:22:41 -0300 Subject: [PATCH 16/57] Windows: reduce stuttering in windowed mode via DwmFlush Resolves issue #1628 --- CMakeLists.txt | 1 + src/modules/window/sdl/Window.cpp | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index b23a1835a..92fb211da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1741,6 +1741,7 @@ if(MSVC) set(LOVE_LINK_LIBRARIES ${LOVE_LINK_LIBRARIES} ws2_32.lib winmm.lib + dwmapi.lib ) set(LOVE_RC diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index 81fccc233..be242eadf 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -44,6 +44,8 @@ #if defined(LOVE_WINDOWS) #include +#include +#include #elif defined(LOVE_MACOSX) #include "common/macosx.h" #endif @@ -1010,6 +1012,22 @@ bool Window::isMinimized() const void Window::swapBuffers() { SDL_GL_SwapWindow(window); + +#ifdef LOVE_WINDOWS + // https://github.com/love2d/love/issues/1628 + // DwmFlush helps avoid apparent stuttering in windowed mode on Windows. Be careful to only call it when + // the compositor may be active and non-adaptive vsync is enabled (it syncs to nearest refresh which stops the + // "adaptive" part of adaptive vsync). + // Calling it directly after vsync seems to have less chance of dropping a frame than directly before. + if (context != nullptr && (!settings.fullscreen || settings.fstype == FULLSCREEN_DESKTOP) && getVSync() > 0) + { + // Desktop composition is always enabled in Windows 8+. But DwmIsCompositionEnabled won't always return true... + // (see DwmIsCompositionEnabled docs). + BOOL compositionEnabled = IsWindows8OrGreater(); + if (compositionEnabled || (SUCCEEDED(DwmIsCompositionEnabled(&compositionEnabled)) && compositionEnabled)) + DwmFlush(); + } +#endif } bool Window::hasFocus() const From 8c86515d048f129281059e31ba48fa9f3b188870 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Thu, 1 Oct 2020 22:09:47 -0300 Subject: [PATCH 17/57] Revert "Windows: reduce stuttering in windowed mode via DwmFlush" This reverts commit 5dd4a463beba7eb956f881b73f6d5572105768e3. --- CMakeLists.txt | 1 - src/modules/window/sdl/Window.cpp | 18 ------------------ 2 files changed, 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 92fb211da..b23a1835a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1741,7 +1741,6 @@ if(MSVC) set(LOVE_LINK_LIBRARIES ${LOVE_LINK_LIBRARIES} ws2_32.lib winmm.lib - dwmapi.lib ) set(LOVE_RC diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index be242eadf..81fccc233 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -44,8 +44,6 @@ #if defined(LOVE_WINDOWS) #include -#include -#include #elif defined(LOVE_MACOSX) #include "common/macosx.h" #endif @@ -1012,22 +1010,6 @@ bool Window::isMinimized() const void Window::swapBuffers() { SDL_GL_SwapWindow(window); - -#ifdef LOVE_WINDOWS - // https://github.com/love2d/love/issues/1628 - // DwmFlush helps avoid apparent stuttering in windowed mode on Windows. Be careful to only call it when - // the compositor may be active and non-adaptive vsync is enabled (it syncs to nearest refresh which stops the - // "adaptive" part of adaptive vsync). - // Calling it directly after vsync seems to have less chance of dropping a frame than directly before. - if (context != nullptr && (!settings.fullscreen || settings.fstype == FULLSCREEN_DESKTOP) && getVSync() > 0) - { - // Desktop composition is always enabled in Windows 8+. But DwmIsCompositionEnabled won't always return true... - // (see DwmIsCompositionEnabled docs). - BOOL compositionEnabled = IsWindows8OrGreater(); - if (compositionEnabled || (SUCCEEDED(DwmIsCompositionEnabled(&compositionEnabled)) && compositionEnabled)) - DwmFlush(); - } -#endif } bool Window::hasFocus() const From c2c59f37a577a7949034258dc772be02a147118d Mon Sep 17 00:00:00 2001 From: 0x7D2B <72297086+0x7D2B@users.noreply.github.com> Date: Tue, 6 Oct 2020 07:45:45 +0000 Subject: [PATCH 18/57] Fix AUR link (love-hg to love-git) --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 0bc7671af..802fdc8fe 100644 --- a/readme.md +++ b/readme.md @@ -67,7 +67,7 @@ There are also unstable/nightly builds: - Builds for some platforms are automatically created after each commit and are available through GitHub's CI interfaces. - Otherwise, some less frequently updated builds can can be found [here][builds]. - For ubuntu linux they are in [ppa:bartbes/love-unstable][unstableppa] -- For arch linux there's [love-hg][aur] in the AUR. +- For arch linux there's [love-git][aur] in the AUR. Dependencies ------------ @@ -93,7 +93,7 @@ Dependencies [builds]: http://love2d.org/builds [stableppa]: https://launchpad.net/~bartbes/+archive/love-stable [unstableppa]: https://launchpad.net/~bartbes/+archive/love-unstable -[aur]: http://aur.archlinux.org/packages/love-hg +[aur]: http://aur.archlinux.org/packages/love-git [love-experiments]: https://github.com/slime73/love-experiments [codestyle]: https://love2d.org/wiki/Code_Style [android-repository]: https://github.com/love2d/love-android From 186fa4e0add07261fb559689e7e229d245d218a1 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Sun, 11 Oct 2020 10:27:32 +0100 Subject: [PATCH 19/57] glad.hpp: Fix include inside a namespace These includes should not be inside a namespace. --- src/libraries/glad/glad.hpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libraries/glad/glad.hpp b/src/libraries/glad/glad.hpp index 195d20544..1672a44cf 100644 --- a/src/libraries/glad/glad.hpp +++ b/src/libraries/glad/glad.hpp @@ -62,14 +62,6 @@ #include -namespace glad { - -bool gladLoadGL(void); - -typedef void* (* LOADER)(const char *name); -bool gladLoadGLLoader(LOADER); - - #ifndef GLEXT_64_TYPES_DEFINED /* This code block is duplicated in glxext.h, so must be protected */ #define GLEXT_64_TYPES_DEFINED @@ -107,6 +99,14 @@ typedef unsigned __int64 uint64_t; #include #endif #endif + +namespace glad { + +bool gladLoadGL(void); + +typedef void* (* LOADER)(const char *name); +bool gladLoadGLLoader(LOADER); + typedef unsigned int GLenum; typedef unsigned char GLboolean; typedef unsigned int GLbitfield; From d083c87d74f9079190505cd1366f4a4315e6a528 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Mon, 12 Oct 2020 17:29:08 -0300 Subject: [PATCH 20/57] Update glslang --- CMakeLists.txt | 3 +- .../xcode/liblove.xcodeproj/project.pbxproj | 10 +- src/libraries/glslang/SPIRV/GLSL.ext.EXT.h | 1 + src/libraries/glslang/SPIRV/GLSL.ext.KHR.h | 7 +- src/libraries/glslang/SPIRV/GlslangToSpv.cpp | 985 +- src/libraries/glslang/SPIRV/GlslangToSpv.h | 0 src/libraries/glslang/SPIRV/Logger.cpp | 2 +- .../glslang/SPIRV/NonSemanticDebugPrintf.h | 50 + src/libraries/glslang/SPIRV/SPVRemapper.cpp | 13 +- src/libraries/glslang/SPIRV/SpvBuilder.cpp | 194 +- src/libraries/glslang/SPIRV/SpvBuilder.h | 138 +- src/libraries/glslang/SPIRV/SpvTools.cpp | 103 +- src/libraries/glslang/SPIRV/SpvTools.h | 16 +- src/libraries/glslang/SPIRV/disassemble.cpp | 14 +- src/libraries/glslang/SPIRV/doc.cpp | 289 +- src/libraries/glslang/SPIRV/doc.h | 1 + src/libraries/glslang/SPIRV/hex_float.h | 4 +- src/libraries/glslang/SPIRV/spirv.hpp | 200 +- src/libraries/glslang/SPIRV/spvIR.h | 27 +- .../glslang/glslang/Include/BaseTypes.h | 90 +- .../glslang/glslang/Include/Common.h | 23 +- .../glslang/glslang/Include/ConstantUnion.h | 2 +- .../glslang/glslang/Include/ResourceLimits.h | 1 + src/libraries/glslang/glslang/Include/Types.h | 60 +- .../glslang/glslang/Include/intermediate.h | 43 +- .../glslang/MachineIndependent/Constant.cpp | 11 +- .../glslang/MachineIndependent/Initialize.cpp | 733 +- .../MachineIndependent/Intermediate.cpp | 399 +- .../MachineIndependent/LiveTraverser.h | 38 +- .../MachineIndependent/ParseContextBase.cpp | 11 +- .../MachineIndependent/ParseHelper.cpp | 562 +- .../glslang/MachineIndependent/ParseHelper.h | 11 +- .../glslang/MachineIndependent/Scan.cpp | 54 +- .../glslang/MachineIndependent/ShaderLang.cpp | 102 +- .../MachineIndependent/SymbolTable.cpp | 8 +- .../glslang/MachineIndependent/SymbolTable.h | 12 +- .../glslang/MachineIndependent/Versions.cpp | 146 +- .../glslang/MachineIndependent/Versions.h | 24 +- .../glslang/MachineIndependent/gl_types.h | 8 + .../MachineIndependent/glslang_tab.cpp | 8776 +++++++++-------- .../MachineIndependent/glslang_tab.cpp.h | 513 +- .../glslang/MachineIndependent/intermOut.cpp | 40 +- .../glslang/MachineIndependent/iomapper.cpp | 106 +- .../glslang/MachineIndependent/iomapper.h | 19 +- .../MachineIndependent/linkValidate.cpp | 142 +- .../MachineIndependent/localintermediate.h | 148 +- .../glslang/MachineIndependent/parseConst.cpp | 18 +- .../MachineIndependent/parseVersions.h | 13 +- .../MachineIndependent/preprocessor/Pp.cpp | 36 +- .../preprocessor/PpContext.cpp | 3 +- .../preprocessor/PpContext.h | 5 +- .../preprocessor/PpScanner.cpp | 82 +- .../propagateNoContraction.cpp | 2 +- .../glslang/MachineIndependent/reflection.cpp | 267 +- .../glslang/MachineIndependent/reflection.h | 4 +- .../glslang/OSDependent/Web/glslang.js.cpp | 26 +- .../glslang/OSDependent/Web/glslang.pre.js | 39 +- .../glslang/glslang/Public/ShaderLang.h | 310 +- .../pch.cpp => build_info.h} | 35 +- src/modules/graphics/ShaderStage.cpp | 1 + 60 files changed, 8915 insertions(+), 6065 deletions(-) mode change 100755 => 100644 src/libraries/glslang/SPIRV/GlslangToSpv.cpp mode change 100755 => 100644 src/libraries/glslang/SPIRV/GlslangToSpv.h create mode 100644 src/libraries/glslang/SPIRV/NonSemanticDebugPrintf.h mode change 100755 => 100644 src/libraries/glslang/SPIRV/spvIR.h mode change 100755 => 100644 src/libraries/glslang/glslang/MachineIndependent/Intermediate.cpp rename src/libraries/glslang/glslang/{MachineIndependent/pch.cpp => build_info.h} (51%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 541b0ea14..66e7a6793 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1338,7 +1338,6 @@ set(LOVE_SRC_3P_GLSLANG_GLSLANG_MACHINEINDEPENDENT src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h src/libraries/glslang/glslang/MachineIndependent/parseVersions.h - src/libraries/glslang/glslang/MachineIndependent/pch.cpp src/libraries/glslang/glslang/MachineIndependent/pch.h src/libraries/glslang/glslang/MachineIndependent/PoolAlloc.cpp src/libraries/glslang/glslang/MachineIndependent/propagateNoContraction.cpp @@ -1379,6 +1378,7 @@ set(LOVE_SRC_3P_GLSLANG_GLSLANG_PUBLIC ) set(LOVE_SRC_3P_GLSLANG_GLSLANG + src/libraries/glslang/glslang/build_info.h ${LOVE_SRC_3P_GLSLANG_GLSLANG_GENERICCODEGEN} ${LOVE_SRC_3P_GLSLANG_GLSLANG_INCLUDE} ${LOVE_SRC_3P_GLSLANG_GLSLANG_MACHINEINDEPENDENT} @@ -1408,6 +1408,7 @@ set(LOVE_SRC_3P_GLSLANG_SPIRV src/libraries/glslang/SPIRV/InReadableOrder.cpp src/libraries/glslang/SPIRV/Logger.cpp src/libraries/glslang/SPIRV/Logger.h + src/libraries/glslang/SPIRV/NonSemanticDebugPrintf.h src/libraries/glslang/SPIRV/spirv.hpp src/libraries/glslang/SPIRV/SpvBuilder.cpp src/libraries/glslang/SPIRV/SpvBuilder.h diff --git a/platform/xcode/liblove.xcodeproj/project.pbxproj b/platform/xcode/liblove.xcodeproj/project.pbxproj index ce4d481ca..953bc1722 100644 --- a/platform/xcode/liblove.xcodeproj/project.pbxproj +++ b/platform/xcode/liblove.xcodeproj/project.pbxproj @@ -795,8 +795,6 @@ FA1E88831DF363DB00E808AA /* Filter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1E88811DF363DB00E808AA /* Filter.cpp */; }; FA1E88841DF363DB00E808AA /* Filter.h in Headers */ = {isa = PBXBuildFile; fileRef = FA1E88821DF363DB00E808AA /* Filter.h */; }; FA1E88851DF363E100E808AA /* Filter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1E88811DF363DB00E808AA /* Filter.cpp */; }; - FA24348421D401CB00B8918A /* pch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA24348021D401CB00B8918A /* pch.cpp */; }; - FA24348521D401CB00B8918A /* pch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA24348021D401CB00B8918A /* pch.cpp */; }; FA24348621D401CB00B8918A /* attribute.h in Headers */ = {isa = PBXBuildFile; fileRef = FA24348121D401CB00B8918A /* attribute.h */; }; FA24348721D401CB00B8918A /* attribute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA24348221D401CB00B8918A /* attribute.cpp */; }; FA24348821D401CB00B8918A /* attribute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA24348221D401CB00B8918A /* attribute.cpp */; }; @@ -1799,7 +1797,6 @@ FA1E887D1DF363CD00E808AA /* Filter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Filter.h; sourceTree = ""; }; FA1E88811DF363DB00E808AA /* Filter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Filter.cpp; sourceTree = ""; }; FA1E88821DF363DB00E808AA /* Filter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Filter.h; sourceTree = ""; }; - FA24348021D401CB00B8918A /* pch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pch.cpp; sourceTree = ""; }; FA24348121D401CB00B8918A /* attribute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = attribute.h; sourceTree = ""; }; FA24348221D401CB00B8918A /* attribute.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = attribute.cpp; sourceTree = ""; }; FA24348321D401CB00B8918A /* pch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pch.h; sourceTree = ""; }; @@ -2009,6 +2006,8 @@ FAE272501C05A15B00A67640 /* ParticleSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParticleSystem.cpp; sourceTree = ""; }; FAE272511C05A15B00A67640 /* ParticleSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParticleSystem.h; sourceTree = ""; }; FAE64A7D2071359C00BC7981 /* libfreetype.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libfreetype.a; sourceTree = ""; }; + FAEC22942534EE6700EBD925 /* NonSemanticDebugPrintf.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NonSemanticDebugPrintf.h; sourceTree = ""; }; + FAEC229F2534F25100EBD925 /* build_info.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = build_info.h; sourceTree = ""; }; FAECA1B01F3164700095D008 /* CompressedSlice.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CompressedSlice.cpp; sourceTree = ""; }; FAECA1B11F3164700095D008 /* CompressedSlice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CompressedSlice.h; sourceTree = ""; }; FAF13FC21E20934C00F898D2 /* CodeGen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeGen.cpp; sourceTree = ""; }; @@ -3591,6 +3590,7 @@ FAF13FC01E20934C00F898D2 /* glslang */ = { isa = PBXGroup; children = ( + FAEC229F2534F25100EBD925 /* build_info.h */, FAF13FC11E20934C00F898D2 /* GenericCodeGen */, FAF13FC41E20934C00F898D2 /* Include */, FAF13FD21E20934C00F898D2 /* MachineIndependent */, @@ -3654,7 +3654,6 @@ FAF13FE61E20934C00F898D2 /* ParseHelper.cpp */, FAF13FE71E20934C00F898D2 /* ParseHelper.h */, FAF13FE81E20934C00F898D2 /* parseVersions.h */, - FA24348021D401CB00B8918A /* pch.cpp */, FA24348321D401CB00B8918A /* pch.h */, FAF13FE91E20934C00F898D2 /* PoolAlloc.cpp */, FAF13FEA1E20934C00F898D2 /* preprocessor */, @@ -3743,6 +3742,7 @@ FAF6C9C623C2DE2900D7B5BC /* InReadableOrder.cpp */, FAF6C9D523C2DE2900D7B5BC /* Logger.cpp */, FAF6C9D723C2DE2900D7B5BC /* Logger.h */, + FAEC22942534EE6700EBD925 /* NonSemanticDebugPrintf.h */, FAF6C9C923C2DE2900D7B5BC /* spirv.hpp */, FAF6C9CA23C2DE2900D7B5BC /* SpvBuilder.cpp */, FAF6C9C223C2DE2900D7B5BC /* SpvBuilder.h */, @@ -4329,7 +4329,6 @@ FA91DA8C1F377C3900C80E33 /* deprecation.cpp in Sources */, FA6A2B6B1F5F7F560074C308 /* DataView.cpp in Sources */, FA0B7E401A95902C000E1D17 /* wrap_ChainShape.cpp in Sources */, - FA24348521D401CB00B8918A /* pch.cpp in Sources */, FA0B7DEC1A95902C000E1D17 /* Cursor.cpp in Sources */, FA0B7D871A95902C000E1D17 /* ImageData.cpp in Sources */, FA0B7E101A95902C000E1D17 /* FrictionJoint.cpp in Sources */, @@ -4728,7 +4727,6 @@ FA0B7DB71A95902C000E1D17 /* Joystick.cpp in Sources */, FA0B7A321A958EA3000E1D17 /* b2Collision.cpp in Sources */, FA91DA8B1F377C3900C80E33 /* deprecation.cpp in Sources */, - FA24348421D401CB00B8918A /* pch.cpp in Sources */, FA0B7E3F1A95902C000E1D17 /* wrap_ChainShape.cpp in Sources */, FA0B7DEB1A95902C000E1D17 /* Cursor.cpp in Sources */, FA0B7D861A95902C000E1D17 /* ImageData.cpp in Sources */, diff --git a/src/libraries/glslang/SPIRV/GLSL.ext.EXT.h b/src/libraries/glslang/SPIRV/GLSL.ext.EXT.h index 40164b618..6eb0eeead 100644 --- a/src/libraries/glslang/SPIRV/GLSL.ext.EXT.h +++ b/src/libraries/glslang/SPIRV/GLSL.ext.EXT.h @@ -35,5 +35,6 @@ static const char* const E_SPV_EXT_shader_viewport_index_layer = "SPV_EXT_shade static const char* const E_SPV_EXT_fragment_fully_covered = "SPV_EXT_fragment_fully_covered"; static const char* const E_SPV_EXT_fragment_invocation_density = "SPV_EXT_fragment_invocation_density"; static const char* const E_SPV_EXT_demote_to_helper_invocation = "SPV_EXT_demote_to_helper_invocation"; +static const char* const E_SPV_EXT_shader_atomic_float_add = "SPV_EXT_shader_atomic_float_add"; #endif // #ifndef GLSLextEXT_H diff --git a/src/libraries/glslang/SPIRV/GLSL.ext.KHR.h b/src/libraries/glslang/SPIRV/GLSL.ext.KHR.h index e58e836a8..d783a8f29 100644 --- a/src/libraries/glslang/SPIRV/GLSL.ext.KHR.h +++ b/src/libraries/glslang/SPIRV/GLSL.ext.KHR.h @@ -1,5 +1,6 @@ /* -** Copyright (c) 2014-2016 The Khronos Group Inc. +** Copyright (c) 2014-2020 The Khronos Group Inc. +** Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. ** ** Permission is hereby granted, free of charge, to any person obtaining a copy ** of this software and/or associated documentation files (the "Materials"), @@ -44,5 +45,7 @@ static const char* const E_SPV_EXT_physical_storage_buffer = "SPV_EXT_physi static const char* const E_SPV_KHR_physical_storage_buffer = "SPV_KHR_physical_storage_buffer"; static const char* const E_SPV_EXT_fragment_shader_interlock = "SPV_EXT_fragment_shader_interlock"; static const char* const E_SPV_KHR_shader_clock = "SPV_KHR_shader_clock"; - +static const char* const E_SPV_KHR_non_semantic_info = "SPV_KHR_non_semantic_info"; +static const char* const E_SPV_KHR_ray_tracing = "SPV_KHR_ray_tracing"; +static const char* const E_SPV_KHR_ray_query = "SPV_KHR_ray_query"; #endif // #ifndef GLSLextKHR_H diff --git a/src/libraries/glslang/SPIRV/GlslangToSpv.cpp b/src/libraries/glslang/SPIRV/GlslangToSpv.cpp old mode 100755 new mode 100644 index 075563662..b86793e1e --- a/src/libraries/glslang/SPIRV/GlslangToSpv.cpp +++ b/src/libraries/glslang/SPIRV/GlslangToSpv.cpp @@ -1,7 +1,8 @@ // // Copyright (C) 2014-2016 LunarG, Inc. -// Copyright (C) 2015-2018 Google, Inc. +// Copyright (C) 2015-2020 Google, Inc. // Copyright (C) 2017 ARM Limited. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -48,13 +49,16 @@ namespace spv { #include "GLSL.ext.EXT.h" #include "GLSL.ext.AMD.h" #include "GLSL.ext.NV.h" + #include "NonSemanticDebugPrintf.h" } // Glslang includes #include "../glslang/MachineIndependent/localintermediate.h" #include "../glslang/MachineIndependent/SymbolTable.h" #include "../glslang/Include/Common.h" -#include "../glslang/Include/revision.h" + +// Build-time generated includes +#include "../glslang/build_info.h" #include #include @@ -187,7 +191,8 @@ protected: void makeGlobalInitializers(const glslang::TIntermSequence&); void visitFunctions(const glslang::TIntermSequence&); void handleFunctionEntry(const glslang::TIntermAggregate* node); - void translateArguments(const glslang::TIntermAggregate& node, std::vector& arguments, spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags); + void translateArguments(const glslang::TIntermAggregate& node, std::vector& arguments, + spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags); void translateArguments(glslang::TIntermUnary& node, std::vector& arguments); spv::Id createImageTextureFunctionCall(glslang::TIntermOperator* node); spv::Id handleUserFunctionCall(const glslang::TIntermAggregate*); @@ -196,28 +201,36 @@ protected: glslang::TBasicType typeProxy, bool reduceComparison = true); spv::Id createBinaryMatrixOperation(spv::Op, OpDecorations&, spv::Id typeId, spv::Id left, spv::Id right); spv::Id createUnaryOperation(glslang::TOperator op, OpDecorations&, spv::Id typeId, spv::Id operand, - glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags); + glslang::TBasicType typeProxy, + const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags); spv::Id createUnaryMatrixOperation(spv::Op op, OpDecorations&, spv::Id typeId, spv::Id operand, glslang::TBasicType typeProxy); spv::Id createConversion(glslang::TOperator op, OpDecorations&, spv::Id destTypeId, spv::Id operand, glslang::TBasicType typeProxy); spv::Id createIntWidthConversion(glslang::TOperator op, spv::Id operand, int vectorSize); spv::Id makeSmearedConstant(spv::Id constant, int vectorSize); - spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags); - spv::Id createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy); - spv::Id CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation, spv::Id typeId, std::vector& operands); - spv::Id createSubgroupOperation(glslang::TOperator op, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy); - spv::Id createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy); + spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, + std::vector& operands, glslang::TBasicType typeProxy, + const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags); + spv::Id createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector& operands, + glslang::TBasicType typeProxy); + spv::Id CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation, + spv::Id typeId, std::vector& operands); + spv::Id createSubgroupOperation(glslang::TOperator op, spv::Id typeId, std::vector& operands, + glslang::TBasicType typeProxy); + spv::Id createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, + std::vector& operands, glslang::TBasicType typeProxy); spv::Id createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId); spv::Id getSymbolId(const glslang::TIntermSymbol* node); void addMeshNVDecoration(spv::Id id, int member, const glslang::TQualifier & qualifier); spv::Id createSpvConstant(const glslang::TIntermTyped&); - spv::Id createSpvConstantFromConstUnionArray(const glslang::TType& type, const glslang::TConstUnionArray&, int& nextConst, bool specConstant); + spv::Id createSpvConstantFromConstUnionArray(const glslang::TType& type, const glslang::TConstUnionArray&, + int& nextConst, bool specConstant); bool isTrivialLeaf(const glslang::TIntermTyped* node); bool isTrivial(const glslang::TIntermTyped* node); spv::Id createShortCircuit(glslang::TOperator, glslang::TIntermTyped& left, glslang::TIntermTyped& right); spv::Id getExtBuiltins(const char* name); - std::pair getForcedType(spv::BuiltIn, const glslang::TType&); + std::pair getForcedType(glslang::TBuiltInVariable builtIn, const glslang::TType&); spv::Id translateForcedType(spv::Id object); spv::Id createCompositeConstruct(spv::Id typeId, std::vector constituents); @@ -233,19 +246,24 @@ protected: spv::Builder builder; bool inEntryPoint; bool entryPointTerminated; - bool linkageOnly; // true when visiting the set of objects in the AST present only for establishing interface, whether or not they were statically used + bool linkageOnly; // true when visiting the set of objects in the AST present only for + // establishing interface, whether or not they were statically used std::set iOSet; // all input/output variables from either static use or declaration of interface const glslang::TIntermediate* glslangIntermediate; bool nanMinMaxClamp; // true if use NMin/NMax/NClamp instead of FMin/FMax/FClamp spv::Id stdBuiltins; + spv::Id nonSemanticDebugPrintf; std::unordered_map extBuiltinMap; std::unordered_map symbolValues; - std::unordered_set rValueParameters; // set of formal function parameters passed as rValues, rather than a pointer + std::unordered_set rValueParameters; // set of formal function parameters passed as rValues, + // rather than a pointer std::unordered_map functionMap; std::unordered_map structMap[glslang::ElpCount][glslang::ElmCount]; // for mapping glslang block indices to spv indices (e.g., due to hidden members): - std::unordered_map > memberRemapper; + std::unordered_map> memberRemapper; + // for mapping glslang symbol struct to symbol Id + std::unordered_map glslangTypeToIdMap; std::stack breakForLoop; // false means break for switch std::unordered_map counterOriginator; // Map pointee types for EbtReference to their forward pointers @@ -265,6 +283,8 @@ spv::SourceLanguage TranslateSourceLanguage(glslang::EShSource source, EProfile { #ifdef GLSLANG_WEB return spv::SourceLanguageESSL; +#elif defined(GLSLANG_ANGLE) + return spv::SourceLanguageGLSL; #endif switch (source) { @@ -297,12 +317,12 @@ spv::ExecutionModel TranslateExecutionModel(EShLanguage stage) case EShLangTessControl: return spv::ExecutionModelTessellationControl; case EShLangTessEvaluation: return spv::ExecutionModelTessellationEvaluation; case EShLangGeometry: return spv::ExecutionModelGeometry; - case EShLangRayGenNV: return spv::ExecutionModelRayGenerationNV; - case EShLangIntersectNV: return spv::ExecutionModelIntersectionNV; - case EShLangAnyHitNV: return spv::ExecutionModelAnyHitNV; - case EShLangClosestHitNV: return spv::ExecutionModelClosestHitNV; - case EShLangMissNV: return spv::ExecutionModelMissNV; - case EShLangCallableNV: return spv::ExecutionModelCallableNV; + case EShLangRayGen: return spv::ExecutionModelRayGenerationKHR; + case EShLangIntersect: return spv::ExecutionModelIntersectionKHR; + case EShLangAnyHit: return spv::ExecutionModelAnyHitKHR; + case EShLangClosestHit: return spv::ExecutionModelClosestHitKHR; + case EShLangMiss: return spv::ExecutionModelMissKHR; + case EShLangCallable: return spv::ExecutionModelCallableKHR; case EShLangTaskNV: return spv::ExecutionModelTaskNV; case EShLangMeshNV: return spv::ExecutionModelMeshNV; #endif @@ -356,11 +376,11 @@ spv::Decoration TranslateBlockDecoration(const glslang::TType& type, bool useSto case glslang::EvqVaryingIn: return spv::DecorationBlock; case glslang::EvqVaryingOut: return spv::DecorationBlock; #ifndef GLSLANG_WEB - case glslang::EvqPayloadNV: return spv::DecorationBlock; - case glslang::EvqPayloadInNV: return spv::DecorationBlock; - case glslang::EvqHitAttrNV: return spv::DecorationBlock; - case glslang::EvqCallableDataNV: return spv::DecorationBlock; - case glslang::EvqCallableDataInNV: return spv::DecorationBlock; + case glslang::EvqPayload: return spv::DecorationBlock; + case glslang::EvqPayloadIn: return spv::DecorationBlock; + case glslang::EvqHitAttr: return spv::DecorationBlock; + case glslang::EvqCallableData: return spv::DecorationBlock; + case glslang::EvqCallableDataIn: return spv::DecorationBlock; #endif default: assert(0); @@ -372,7 +392,8 @@ spv::Decoration TranslateBlockDecoration(const glslang::TType& type, bool useSto } // Translate glslang type to SPIR-V memory decorations. -void TranslateMemoryDecoration(const glslang::TQualifier& qualifier, std::vector& memory, bool useVulkanMemoryModel) +void TranslateMemoryDecoration(const glslang::TQualifier& qualifier, std::vector& memory, + bool useVulkanMemoryModel) { if (!useVulkanMemoryModel) { if (qualifier.isCoherent()) @@ -431,11 +452,11 @@ spv::Decoration TranslateLayoutDecoration(const glslang::TType& type, glslang::T } return spv::DecorationMax; #ifndef GLSLANG_WEB - case glslang::EvqPayloadNV: - case glslang::EvqPayloadInNV: - case glslang::EvqHitAttrNV: - case glslang::EvqCallableDataNV: - case glslang::EvqCallableDataInNV: + case glslang::EvqPayload: + case glslang::EvqPayloadIn: + case glslang::EvqHitAttr: + case glslang::EvqCallableData: + case glslang::EvqCallableDataIn: return spv::DecorationMax; #endif default: @@ -527,15 +548,11 @@ spv::MemoryAccessMask TGlslangToSpvTraverser::TranslateMemoryAccess( if (!glslangIntermediate->usingVulkanMemoryModel() || coherentFlags.isImage) return mask; - if (coherentFlags.volatil || - coherentFlags.coherent || - coherentFlags.devicecoherent || - coherentFlags.queuefamilycoherent || - coherentFlags.workgroupcoherent || - coherentFlags.subgroupcoherent) { + if (coherentFlags.isVolatile() || coherentFlags.anyCoherent()) { mask = mask | spv::MemoryAccessMakePointerAvailableKHRMask | spv::MemoryAccessMakePointerVisibleKHRMask; } + if (coherentFlags.nonprivate) { mask = mask | spv::MemoryAccessNonPrivatePointerKHRMask; } @@ -560,11 +577,7 @@ spv::ImageOperandsMask TGlslangToSpvTraverser::TranslateImageOperands( return mask; if (coherentFlags.volatil || - coherentFlags.coherent || - coherentFlags.devicecoherent || - coherentFlags.queuefamilycoherent || - coherentFlags.workgroupcoherent || - coherentFlags.subgroupcoherent) { + coherentFlags.anyCoherent()) { mask = mask | spv::ImageOperandsMakeTexelAvailableKHRMask | spv::ImageOperandsMakeTexelVisibleKHRMask; } @@ -593,14 +606,11 @@ spv::Builder::AccessChain::CoherentFlags TGlslangToSpvTraverser::TranslateCohere flags.workgroupcoherent = type.getQualifier().workgroupcoherent || type.getQualifier().storage == glslang::EvqShared; flags.subgroupcoherent = type.getQualifier().subgroupcoherent; + flags.shadercallcoherent = type.getQualifier().shadercallcoherent; flags.volatil = type.getQualifier().volatil; // *coherent variables are implicitly nonprivate in GLSL flags.nonprivate = type.getQualifier().nonprivate || - flags.subgroupcoherent || - flags.workgroupcoherent || - flags.queuefamilycoherent || - flags.devicecoherent || - flags.coherent || + flags.anyCoherent() || flags.volatil; flags.isImage = type.getBasicType() == glslang::EbtSampler; #endif @@ -624,6 +634,8 @@ spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope( scope = spv::ScopeWorkgroup; } else if (coherentFlags.subgroupcoherent) { scope = spv::ScopeSubgroup; + } else if (coherentFlags.shadercallcoherent) { + scope = spv::ScopeShaderCallKHR; } if (glslangIntermediate->usingVulkanMemoryModel() && scope == spv::ScopeDevice) { builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR); @@ -638,7 +650,8 @@ spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope( // is generated only when using the variable in an executable instruction, but not when // just declaring a struct member variable with it. This is true for PointSize, // ClipDistance, and CullDistance. -spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltInVariable builtIn, bool memberDeclaration) +spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltInVariable builtIn, + bool memberDeclaration) { switch (builtIn) { case glslang::EbvPointSize: @@ -931,34 +944,38 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI return spv::BuiltInInvocationsPerPixelNV; // ray tracing - case glslang::EbvLaunchIdNV: - return spv::BuiltInLaunchIdNV; - case glslang::EbvLaunchSizeNV: - return spv::BuiltInLaunchSizeNV; - case glslang::EbvWorldRayOriginNV: - return spv::BuiltInWorldRayOriginNV; - case glslang::EbvWorldRayDirectionNV: - return spv::BuiltInWorldRayDirectionNV; - case glslang::EbvObjectRayOriginNV: - return spv::BuiltInObjectRayOriginNV; - case glslang::EbvObjectRayDirectionNV: - return spv::BuiltInObjectRayDirectionNV; - case glslang::EbvRayTminNV: - return spv::BuiltInRayTminNV; - case glslang::EbvRayTmaxNV: - return spv::BuiltInRayTmaxNV; - case glslang::EbvInstanceCustomIndexNV: - return spv::BuiltInInstanceCustomIndexNV; - case glslang::EbvHitTNV: - return spv::BuiltInHitTNV; - case glslang::EbvHitKindNV: - return spv::BuiltInHitKindNV; - case glslang::EbvObjectToWorldNV: - return spv::BuiltInObjectToWorldNV; - case glslang::EbvWorldToObjectNV: - return spv::BuiltInWorldToObjectNV; - case glslang::EbvIncomingRayFlagsNV: - return spv::BuiltInIncomingRayFlagsNV; + case glslang::EbvLaunchId: + return spv::BuiltInLaunchIdKHR; + case glslang::EbvLaunchSize: + return spv::BuiltInLaunchSizeKHR; + case glslang::EbvWorldRayOrigin: + return spv::BuiltInWorldRayOriginKHR; + case glslang::EbvWorldRayDirection: + return spv::BuiltInWorldRayDirectionKHR; + case glslang::EbvObjectRayOrigin: + return spv::BuiltInObjectRayOriginKHR; + case glslang::EbvObjectRayDirection: + return spv::BuiltInObjectRayDirectionKHR; + case glslang::EbvRayTmin: + return spv::BuiltInRayTminKHR; + case glslang::EbvRayTmax: + return spv::BuiltInRayTmaxKHR; + case glslang::EbvInstanceCustomIndex: + return spv::BuiltInInstanceCustomIndexKHR; + case glslang::EbvHitT: + return spv::BuiltInHitTKHR; + case glslang::EbvHitKind: + return spv::BuiltInHitKindKHR; + case glslang::EbvObjectToWorld: + case glslang::EbvObjectToWorld3x4: + return spv::BuiltInObjectToWorldKHR; + case glslang::EbvWorldToObject: + case glslang::EbvWorldToObject3x4: + return spv::BuiltInWorldToObjectKHR; + case glslang::EbvIncomingRayFlags: + return spv::BuiltInIncomingRayFlagsKHR; + case glslang::EbvGeometryIndex: + return spv::BuiltInRayGeometryIndexKHR; // barycentrics case glslang::EbvBaryCoordNV: @@ -1104,7 +1121,8 @@ spv::ImageFormat TGlslangToSpvTraverser::TranslateImageFormat(const glslang::TTy } } -spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSelectionControl(const glslang::TIntermSelection& selectionNode) const +spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSelectionControl( + const glslang::TIntermSelection& selectionNode) const { if (selectionNode.getFlatten()) return spv::SelectionControlFlattenMask; @@ -1113,7 +1131,8 @@ spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSelectionControl(cons return spv::SelectionControlMaskNone; } -spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSwitchControl(const glslang::TIntermSwitch& switchNode) const +spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSwitchControl(const glslang::TIntermSwitch& switchNode) + const { if (switchNode.getFlatten()) return spv::SelectionControlFlattenMask; @@ -1167,6 +1186,8 @@ spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(const glslang: // Translate glslang type to SPIR-V storage class. spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::TType& type) { + if (type.getBasicType() == glslang::EbtRayQuery) + return spv::StorageClassFunction; if (type.getQualifier().isPipeInput()) return spv::StorageClassInput; if (type.getQualifier().isPipeOutput()) @@ -1181,8 +1202,8 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T } if (type.getQualifier().isUniformOrBuffer() && - type.getQualifier().isShaderRecordNV()) { - return spv::StorageClassShaderRecordBufferNV; + type.getQualifier().isShaderRecord()) { + return spv::StorageClassShaderRecordBufferKHR; } if (glslangIntermediate->usingStorageBuffer() && type.getQualifier().storage == glslang::EvqBuffer) { @@ -1204,11 +1225,11 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T case glslang::EvqTemporary: return spv::StorageClassFunction; case glslang::EvqShared: return spv::StorageClassWorkgroup; #ifndef GLSLANG_WEB - case glslang::EvqPayloadNV: return spv::StorageClassRayPayloadNV; - case glslang::EvqPayloadInNV: return spv::StorageClassIncomingRayPayloadNV; - case glslang::EvqHitAttrNV: return spv::StorageClassHitAttributeNV; - case glslang::EvqCallableDataNV: return spv::StorageClassCallableDataNV; - case glslang::EvqCallableDataInNV: return spv::StorageClassIncomingCallableDataNV; + case glslang::EvqPayload: return spv::StorageClassRayPayloadKHR; + case glslang::EvqPayloadIn: return spv::StorageClassIncomingRayPayloadKHR; + case glslang::EvqHitAttr: return spv::StorageClassHitAttributeKHR; + case glslang::EvqCallableData: return spv::StorageClassCallableDataKHR; + case glslang::EvqCallableDataIn: return spv::StorageClassIncomingCallableDataKHR; #endif default: assert(0); @@ -1268,14 +1289,15 @@ bool IsDescriptorResource(const glslang::TType& type) // uniform and buffer blocks are included, unless it is a push_constant if (type.getBasicType() == glslang::EbtBlock) return type.getQualifier().isUniformOrBuffer() && - ! type.getQualifier().isShaderRecordNV() && + ! type.getQualifier().isShaderRecord() && ! type.getQualifier().isPushConstant(); // non block... // basically samplerXXX/subpass/sampler/texture are all included // if they are the global-scope-class, not the function parameter // (or local, if they ever exist) class. - if (type.getBasicType() == glslang::EbtSampler) + if (type.getBasicType() == glslang::EbtSampler || + type.getBasicType() == glslang::EbtAccStruct) return type.getQualifier().isUniformOrBuffer(); // None of the above. @@ -1318,6 +1340,8 @@ void InheritQualifiers(glslang::TQualifier& child, const glslang::TQualifier& pa child.workgroupcoherent = true; if (parent.subgroupcoherent) child.subgroupcoherent = true; + if (parent.shadercallcoherent) + child.shadercallcoherent = true; if (parent.nonprivate) child.nonprivate = true; if (parent.volatil) @@ -1348,16 +1372,18 @@ bool HasNonLayoutQualifiers(const glslang::TType& type, const glslang::TQualifie // Implement the TGlslangToSpvTraverser class. // -TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const glslang::TIntermediate* glslangIntermediate, - spv::SpvBuildLogger* buildLogger, glslang::SpvOptions& options) - : TIntermTraverser(true, false, true), - options(options), - shaderEntry(nullptr), currentFunction(nullptr), - sequenceDepth(0), logger(buildLogger), - builder(spvVersion, (glslang::GetKhronosToolId() << 16) | glslang::GetSpirvGeneratorVersion(), logger), - inEntryPoint(false), entryPointTerminated(false), linkageOnly(false), - glslangIntermediate(glslangIntermediate), - nanMinMaxClamp(glslangIntermediate->getNanMinMaxClamp()) +TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, + const glslang::TIntermediate* glslangIntermediate, + spv::SpvBuildLogger* buildLogger, glslang::SpvOptions& options) : + TIntermTraverser(true, false, true), + options(options), + shaderEntry(nullptr), currentFunction(nullptr), + sequenceDepth(0), logger(buildLogger), + builder(spvVersion, (glslang::GetKhronosToolId() << 16) | glslang::GetSpirvGeneratorVersion(), logger), + inEntryPoint(false), entryPointTerminated(false), linkageOnly(false), + glslangIntermediate(glslangIntermediate), + nanMinMaxClamp(glslangIntermediate->getNanMinMaxClamp()), + nonSemanticDebugPrintf(0) { spv::ExecutionModel executionModel = TranslateExecutionModel(glslangIntermediate->getStage()); @@ -1400,7 +1426,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl addressingModel = spv::AddressingModelPhysicalStorageBuffer64EXT; builder.addIncorporatedExtension(spv::E_SPV_EXT_physical_storage_buffer, spv::Spv_1_5); builder.addCapability(spv::CapabilityPhysicalStorageBufferAddressesEXT); - }; + } if (glslangIntermediate->usingVulkanMemoryModel()) { memoryModel = spv::MemoryModelVulkanKHR; builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); @@ -1427,6 +1453,10 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl builder.addExecutionMode(shaderEntry, spv::ExecutionModeXfb); } + if (glslangIntermediate->getLayoutPrimitiveCulling()) { + builder.addCapability(spv::CapabilityRayTraversalPrimitiveCullingProvisionalKHR); + } + unsigned int mode; switch (glslangIntermediate->getStage()) { case EShLangVertex: @@ -1456,6 +1486,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl builder.addExecutionMode(shaderEntry, spv::ExecutionModeDepthReplacing); #ifndef GLSLANG_WEB + switch(glslangIntermediate->getDepth()) { case glslang::EldGreater: mode = spv::ExecutionModeDepthGreater; break; case glslang::EldLess: mode = spv::ExecutionModeDepthLess; break; @@ -1493,7 +1524,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl builder.addExtension(spv::E_SPV_EXT_fragment_shader_interlock); } #endif - break; + break; case EShLangCompute: builder.addCapability(spv::CapabilityShader); @@ -1518,7 +1549,8 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl glslang::TLayoutGeometry primitive; if (glslangIntermediate->getStage() == EShLangTessControl) { - builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices()); + builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, + glslangIntermediate->getVertices()); primitive = glslangIntermediate->getOutputPrimitive(); } else { primitive = glslangIntermediate->getInputPrimitive(); @@ -1580,15 +1612,24 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices()); break; - case EShLangRayGenNV: - case EShLangIntersectNV: - case EShLangAnyHitNV: - case EShLangClosestHitNV: - case EShLangMissNV: - case EShLangCallableNV: - builder.addCapability(spv::CapabilityRayTracingNV); - builder.addExtension("SPV_NV_ray_tracing"); + case EShLangRayGen: + case EShLangIntersect: + case EShLangAnyHit: + case EShLangClosestHit: + case EShLangMiss: + case EShLangCallable: + { + auto& extensions = glslangIntermediate->getRequestedExtensions(); + if (extensions.find("GL_NV_ray_tracing") == extensions.end()) { + builder.addCapability(spv::CapabilityRayTracingProvisionalKHR); + builder.addExtension("SPV_KHR_ray_tracing"); + } + else { + builder.addCapability(spv::CapabilityRayTracingNV); + builder.addExtension("SPV_NV_ray_tracing"); + } break; + } case EShLangTaskNV: case EShLangMeshNV: builder.addCapability(spv::CapabilityMeshShadingNV); @@ -1597,8 +1638,10 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl glslangIntermediate->getLocalSize(1), glslangIntermediate->getLocalSize(2)); if (glslangIntermediate->getStage() == EShLangMeshNV) { - builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices()); - builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputPrimitivesNV, glslangIntermediate->getPrimitives()); + builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, + glslangIntermediate->getVertices()); + builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputPrimitivesNV, + glslangIntermediate->getPrimitives()); switch (glslangIntermediate->getOutputPrimitive()) { case glslang::ElgPoints: mode = spv::ExecutionModeOutputPoints; break; @@ -1661,6 +1704,9 @@ void TGlslangToSpvTraverser::dumpSpv(std::vector& out) void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol) { SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder); + if (symbol->getType().isStruct()) + glslangTypeToIdMap[symbol->getType().getStruct()] = symbol->getId(); + if (symbol->getType().getQualifier().isSpecConstant()) spec_constant_op_mode_setter.turnOnSpecConstantOpMode(); @@ -1669,20 +1715,24 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol) spv::Id id = getSymbolId(symbol); if (builder.isPointer(id)) { - // Include all "static use" and "linkage only" interface variables on the OpEntryPoint instruction - // Consider adding to the OpEntryPoint interface list. - // Only looking at structures if they have at least one member. - if (!symbol->getType().isStruct() || symbol->getType().getStruct()->size() > 0) { - spv::StorageClass sc = builder.getStorageClass(id); - // Before SPIR-V 1.4, we only want to include Input and Output. - // Starting with SPIR-V 1.4, we want all globals. - if ((glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4 && sc != spv::StorageClassFunction) || - (sc == spv::StorageClassInput || sc == spv::StorageClassOutput)) { - iOSet.insert(id); + if (!symbol->getType().getQualifier().isParamInput() && + !symbol->getType().getQualifier().isParamOutput()) { + // Include all "static use" and "linkage only" interface variables on the OpEntryPoint instruction + // Consider adding to the OpEntryPoint interface list. + // Only looking at structures if they have at least one member. + if (!symbol->getType().isStruct() || symbol->getType().getStruct()->size() > 0) { + spv::StorageClass sc = builder.getStorageClass(id); + // Before SPIR-V 1.4, we only want to include Input and Output. + // Starting with SPIR-V 1.4, we want all globals. + if ((glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4 && builder.isGlobalStorage(id)) || + (sc == spv::StorageClassInput || sc == spv::StorageClassOutput)) { + iOSet.insert(id); + } } } - // If the SPIR-V type is required to be different than the AST type, + // If the SPIR-V type is required to be different than the AST type + // (for ex SubgroupMasks or 3x4 ObjectToWorld/WorldToObject matrices), // translate now from the SPIR-V type to the AST type, for the consuming // operation. // Note this turns it from an l-value to an r-value. @@ -1753,6 +1803,12 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol) bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::TIntermBinary* node) { builder.setLine(node->getLoc().line, node->getLoc().getFilename()); + if (node->getLeft()->getAsSymbolNode() != nullptr && node->getLeft()->getType().isStruct()) { + glslangTypeToIdMap[node->getLeft()->getType().getStruct()] = node->getLeft()->getAsSymbolNode()->getId(); + } + if (node->getRight()->getAsSymbolNode() != nullptr && node->getRight()->getType().isStruct()) { + glslangTypeToIdMap[node->getRight()->getType().getStruct()] = node->getRight()->getAsSymbolNode()->getId(); + } SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder); if (node->getType().getQualifier().isSpecConstant()) @@ -1836,7 +1892,8 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T int dummySize; builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()), TranslateCoherent(node->getLeft()->getType()), - glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize)); + glslangIntermediate->getBaseAlignmentScalar( + node->getLeft()->getType(), dummySize)); } else { // Load through a block reference is performed with a dot operator that @@ -1857,13 +1914,18 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T { // This may be, e.g., an anonymous block-member selection, which generally need // index remapping due to hidden members in anonymous blocks. - std::vector& remapper = memberRemapper[node->getLeft()->getType().getStruct()]; - assert(remapper.size() > 0); - spvIndex = remapper[glslangIndex]; + int glslangId = glslangTypeToIdMap[node->getLeft()->getType().getStruct()]; + if (memberRemapper.find(glslangId) != memberRemapper.end()) { + std::vector& remapper = memberRemapper[glslangId]; + assert(remapper.size() > 0); + spvIndex = remapper[glslangIndex]; + } } // normal case for indexing array or structure or block - builder.accessChainPush(builder.makeIntConstant(spvIndex), TranslateCoherent(node->getLeft()->getType()), node->getLeft()->getType().getBufferReferenceAlignment()); + builder.accessChainPush(builder.makeIntConstant(spvIndex), + TranslateCoherent(node->getLeft()->getType()), + node->getLeft()->getType().getBufferReferenceAlignment()); // Add capabilities here for accessing PointSize and clip/cull distance. // We have deferred generation of associated capabilities until now. @@ -1900,9 +1962,11 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T int dummySize; builder.accessChainPushComponent(index, convertGlslangToSpvType(node->getLeft()->getType()), TranslateCoherent(node->getLeft()->getType()), - glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize)); + glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), + dummySize)); } else - builder.accessChainPush(index, TranslateCoherent(node->getLeft()->getType()), node->getLeft()->getType().getBufferReferenceAlignment()); + builder.accessChainPush(index, TranslateCoherent(node->getLeft()->getType()), + node->getLeft()->getType().getBufferReferenceAlignment()); } return false; case glslang::EOpVectorSwizzle: @@ -1913,7 +1977,8 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T int dummySize; builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()), TranslateCoherent(node->getLeft()->getType()), - glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize)); + glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), + dummySize)); } return false; case glslang::EOpMatrixSwizzle: @@ -1929,7 +1994,8 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T if (isTrivial(node->getRight()->getAsTyped())) break; // handle below as a normal binary operation // otherwise, we need to do dynamic short circuiting on the right operand - spv::Id result = createShortCircuit(node->getOp(), *node->getLeft()->getAsTyped(), *node->getRight()->getAsTyped()); + spv::Id result = createShortCircuit(node->getOp(), *node->getLeft()->getAsTyped(), + *node->getRight()->getAsTyped()); builder.clearAccessChain(); builder.setAccessChainRValue(result); } @@ -1971,16 +2037,16 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T // Figure out what, if any, type changes are needed when accessing a specific built-in. // Returns . // Also see comment for 'forceType', regarding tracking SPIR-V-required types. -std::pair TGlslangToSpvTraverser::getForcedType(spv::BuiltIn builtIn, +std::pair TGlslangToSpvTraverser::getForcedType(glslang::TBuiltInVariable glslangBuiltIn, const glslang::TType& glslangType) { - switch(builtIn) + switch(glslangBuiltIn) { - case spv::BuiltInSubgroupEqMask: - case spv::BuiltInSubgroupGeMask: - case spv::BuiltInSubgroupGtMask: - case spv::BuiltInSubgroupLeMask: - case spv::BuiltInSubgroupLtMask: { + case glslang::EbvSubGroupEqMask: + case glslang::EbvSubGroupGeMask: + case glslang::EbvSubGroupGtMask: + case glslang::EbvSubGroupLeMask: + case glslang::EbvSubGroupLtMask: { // these require changing a 64-bit scaler -> a vector of 32-bit components if (glslangType.isVector()) break; @@ -1988,6 +2054,15 @@ std::pair TGlslangToSpvTraverser::getForcedType(spv::BuiltIn b builder.makeUintType(64)); return ret; } + // There are no SPIR-V builtins defined for these and map onto original non-transposed + // builtins. During visitBinary we insert a transpose + case glslang::EbvWorldToObject3x4: + case glslang::EbvObjectToWorld3x4: { + spv::Id mat43 = builder.makeMatrixType(builder.makeFloatType(32), 4, 3); + spv::Id mat34 = builder.makeMatrixType(builder.makeFloatType(32), 3, 4); + std::pair ret(mat43, mat34); + return ret; + } default: break; } @@ -2026,7 +2101,15 @@ spv::Id TGlslangToSpvTraverser::translateForcedType(spv::Id object) } else { logger->missingFunctionality("forcing 32-bit vector type to non 64-bit scalar"); } - } else { + } else if (builder.isMatrixType(objectTypeId)) { + // There are no SPIR-V builtins defined for 3x4 variants of ObjectToWorld/WorldToObject + // and we insert a transpose after loading the original non-transposed builtins + builder.clearAccessChain(); + builder.setAccessChainLValue(object); + object = builder.accessChainLoad(spv::NoPrecision, spv::DecorationMax, objectTypeId); + return builder.createUnaryOp(spv::OpTranspose, desiredTypeId, object); + + } else { logger->missingFunctionality("forcing non 32-bit vector type"); } @@ -2077,7 +2160,8 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI } else { glslang::TIntermTyped* block = node->getOperand()->getAsBinaryNode()->getLeft(); block->traverse(this); - unsigned int member = node->getOperand()->getAsBinaryNode()->getRight()->getAsConstantUnion()->getConstArray()[0].getUConst(); + unsigned int member = node->getOperand()->getAsBinaryNode()->getRight()->getAsConstantUnion() + ->getConstArray()[0].getUConst(); length = builder.createArrayLength(builder.accessChainGetLValue(), member); } @@ -2103,7 +2187,8 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI // Does it need a swizzle inversion? If so, evaluation is inverted; // operate first on the swizzle base, then apply the swizzle. spv::Id invertedType = spv::NoType; - auto resultType = [&invertedType, &node, this](){ return invertedType != spv::NoType ? invertedType : convertGlslangToSpvType(node->getType()); }; + auto resultType = [&invertedType, &node, this](){ return invertedType != spv::NoType ? + invertedType : convertGlslangToSpvType(node->getType()); }; if (node->getOp() == glslang::EOpInterpolateAtCentroid) invertedType = getInvertedSwizzleType(*node->getOperand()); @@ -2124,7 +2209,15 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI if (node->getOp() == glslang::EOpAtomicCounterIncrement || node->getOp() == glslang::EOpAtomicCounterDecrement || node->getOp() == glslang::EOpAtomicCounter || - node->getOp() == glslang::EOpInterpolateAtCentroid) { + node->getOp() == glslang::EOpInterpolateAtCentroid || + node->getOp() == glslang::EOpRayQueryProceed || + node->getOp() == glslang::EOpRayQueryGetRayTMin || + node->getOp() == glslang::EOpRayQueryGetRayFlags || + node->getOp() == glslang::EOpRayQueryGetWorldRayOrigin || + node->getOp() == glslang::EOpRayQueryGetWorldRayDirection || + node->getOp() == glslang::EOpRayQueryGetIntersectionCandidateAABBOpaque || + node->getOp() == glslang::EOpRayQueryTerminate || + node->getOp() == glslang::EOpRayQueryConfirmIntersection) { operand = builder.accessChainGetLValue(); // Special case l-value operands lvalueCoherentFlags = builder.getAccessChain().coherentFlags; lvalueCoherentFlags |= TranslateCoherent(operandNode->getAsTyped()->getType()); @@ -2140,11 +2233,13 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI // it could be a conversion if (! result) - result = createConversion(node->getOp(), decorations, resultType(), operand, node->getOperand()->getBasicType()); + result = createConversion(node->getOp(), decorations, resultType(), operand, + node->getOperand()->getBasicType()); // if not, then possibly an operation if (! result) - result = createUnaryOperation(node->getOp(), decorations, resultType(), operand, node->getOperand()->getBasicType(), lvalueCoherentFlags); + result = createUnaryOperation(node->getOp(), decorations, resultType(), operand, + node->getOperand()->getBasicType(), lvalueCoherentFlags); if (result) { if (invertedType) { @@ -2215,6 +2310,12 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI case glslang::EOpEndStreamPrimitive: builder.createNoResultOp(spv::OpEndStreamPrimitive, operand); return false; + case glslang::EOpRayQueryTerminate: + builder.createNoResultOp(spv::OpRayQueryTerminateKHR, operand); + return false; + case glslang::EOpRayQueryConfirmIntersection: + builder.createNoResultOp(spv::OpRayQueryConfirmIntersectionKHR, operand); + return false; #endif default: @@ -2237,7 +2338,8 @@ spv::Id TGlslangToSpvTraverser::createCompositeConstruct(spv::Id resultTypeId, s std::vector rTypeConstituents; int numrTypeConstituents = builder.getNumTypeConstituents(rType); for (int i = 0; i < numrTypeConstituents; ++i) { - rTypeConstituents.push_back(builder.createCompositeExtract(constituent, builder.getContainedTypeId(rType, i), i)); + rTypeConstituents.push_back(builder.createCompositeExtract(constituent, + builder.getContainedTypeId(rType, i), i)); } constituents[c] = createCompositeConstruct(lType, rTypeConstituents); } else { @@ -2263,8 +2365,14 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt spec_constant_op_mode_setter.turnOnSpecConstantOpMode(); spv::Id result = spv::NoResult; - spv::Id invertedType = spv::NoType; // to use to override the natural type of the node - auto resultType = [&invertedType, &node, this](){ return invertedType != spv::NoType ? invertedType : convertGlslangToSpvType(node->getType()); }; + spv::Id invertedType = spv::NoType; // to use to override the natural type of the node + std::vector complexLvalues; // for holding swizzling l-values too complex for + // SPIR-V, for an out parameter + std::vector temporaryLvalues; // temporaries to pass, as proxies for complexLValues + + auto resultType = [&invertedType, &node, this](){ return invertedType != spv::NoType ? + invertedType : + convertGlslangToSpvType(node->getType()); }; // try texturing result = createImageTextureFunctionCall(node); @@ -2368,7 +2476,6 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt builder.setLine(node->getLoc().line, node->getLoc().getFilename()); if (node->isUserDefined()) result = handleUserFunctionCall(node); - // assert(result); // this can happen for bad shaders because the call graph completeness checking is not yet done if (result) { builder.clearAccessChain(); builder.setAccessChainRValue(result); @@ -2619,13 +2726,43 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt binOp = node->getOp(); break; - case glslang::EOpIgnoreIntersectionNV: - case glslang::EOpTerminateRayNV: - case glslang::EOpTraceNV: - case glslang::EOpExecuteCallableNV: + case glslang::EOpIgnoreIntersection: + case glslang::EOpTerminateRay: + case glslang::EOpTrace: + case glslang::EOpExecuteCallable: case glslang::EOpWritePackedPrimitiveIndices4x8NV: noReturnValue = true; break; + case glslang::EOpRayQueryInitialize: + case glslang::EOpRayQueryTerminate: + case glslang::EOpRayQueryGenerateIntersection: + case glslang::EOpRayQueryConfirmIntersection: + builder.addExtension("SPV_KHR_ray_query"); + builder.addCapability(spv::CapabilityRayQueryProvisionalKHR); + noReturnValue = true; + break; + case glslang::EOpRayQueryProceed: + case glslang::EOpRayQueryGetIntersectionType: + case glslang::EOpRayQueryGetRayTMin: + case glslang::EOpRayQueryGetRayFlags: + case glslang::EOpRayQueryGetIntersectionT: + case glslang::EOpRayQueryGetIntersectionInstanceCustomIndex: + case glslang::EOpRayQueryGetIntersectionInstanceId: + case glslang::EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset: + case glslang::EOpRayQueryGetIntersectionGeometryIndex: + case glslang::EOpRayQueryGetIntersectionPrimitiveIndex: + case glslang::EOpRayQueryGetIntersectionBarycentrics: + case glslang::EOpRayQueryGetIntersectionFrontFace: + case glslang::EOpRayQueryGetIntersectionCandidateAABBOpaque: + case glslang::EOpRayQueryGetIntersectionObjectRayDirection: + case glslang::EOpRayQueryGetIntersectionObjectRayOrigin: + case glslang::EOpRayQueryGetWorldRayDirection: + case glslang::EOpRayQueryGetWorldRayOrigin: + case glslang::EOpRayQueryGetIntersectionObjectToWorld: + case glslang::EOpRayQueryGetIntersectionWorldToObject: + builder.addExtension("SPV_KHR_ray_query"); + builder.addCapability(spv::CapabilityRayQueryProvisionalKHR); + break; case glslang::EOpCooperativeMatrixLoad: case glslang::EOpCooperativeMatrixStore: noReturnValue = true; @@ -2637,6 +2774,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt break; #endif + case glslang::EOpDebugPrintf: + noReturnValue = true; + break; + default: break; } @@ -2688,6 +2829,28 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt lvalue = true; break; + case glslang::EOpRayQueryInitialize: + case glslang::EOpRayQueryTerminate: + case glslang::EOpRayQueryConfirmIntersection: + case glslang::EOpRayQueryProceed: + case glslang::EOpRayQueryGenerateIntersection: + case glslang::EOpRayQueryGetIntersectionType: + case glslang::EOpRayQueryGetIntersectionT: + case glslang::EOpRayQueryGetIntersectionInstanceCustomIndex: + case glslang::EOpRayQueryGetIntersectionInstanceId: + case glslang::EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset: + case glslang::EOpRayQueryGetIntersectionGeometryIndex: + case glslang::EOpRayQueryGetIntersectionPrimitiveIndex: + case glslang::EOpRayQueryGetIntersectionBarycentrics: + case glslang::EOpRayQueryGetIntersectionFrontFace: + case glslang::EOpRayQueryGetIntersectionObjectRayDirection: + case glslang::EOpRayQueryGetIntersectionObjectRayOrigin: + case glslang::EOpRayQueryGetIntersectionObjectToWorld: + case glslang::EOpRayQueryGetIntersectionWorldToObject: + if (arg == 0) + lvalue = true; + break; + case glslang::EOpAtomicAdd: case glslang::EOpAtomicMin: case glslang::EOpAtomicMax: @@ -2713,9 +2876,14 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt // Does it need a swizzle inversion? If so, evaluation is inverted; // operate first on the swizzle base, then apply the swizzle. + // That is, we transform + // + // interpolate(v.zy) -> interpolate(v).zy + // if (glslangOperands[0]->getAsOperator() && glslangOperands[0]->getAsOperator()->getOp() == glslang::EOpVectorSwizzle) - invertedType = convertGlslangToSpvType(glslangOperands[0]->getAsBinaryNode()->getLeft()->getType()); + invertedType = convertGlslangToSpvType( + glslangOperands[0]->getAsBinaryNode()->getLeft()->getType()); } break; case glslang::EOpAtomicLoad: @@ -2775,8 +2943,9 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt builder.setAccessChain(save); // Point to the first element of the array. - builder.accessChainPush(elementId, TranslateCoherent(glslangOperands[arg]->getAsTyped()->getType()), - glslangOperands[arg]->getAsTyped()->getType().getBufferReferenceAlignment()); + builder.accessChainPush(elementId, + TranslateCoherent(glslangOperands[arg]->getAsTyped()->getType()), + glslangOperands[arg]->getAsTyped()->getType().getBufferReferenceAlignment()); spv::Builder::AccessChain::CoherentFlags coherentFlags = builder.getAccessChain().coherentFlags; unsigned int alignment = builder.getAccessChain().alignment; @@ -2786,7 +2955,8 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt memoryAccess &= ~spv::MemoryAccessMakePointerAvailableKHRMask; if (node->getOp() == glslang::EOpCooperativeMatrixStore) memoryAccess &= ~spv::MemoryAccessMakePointerVisibleKHRMask; - if (builder.getStorageClass(builder.getAccessChain().base) == spv::StorageClassPhysicalStorageBufferEXT) { + if (builder.getStorageClass(builder.getAccessChain().base) == + spv::StorageClassPhysicalStorageBufferEXT) { memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask); } @@ -2796,8 +2966,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt memoryAccessOperands.push_back(spv::IdImmediate(false, alignment)); } - if (memoryAccess & (spv::MemoryAccessMakePointerAvailableKHRMask | spv::MemoryAccessMakePointerVisibleKHRMask)) { - memoryAccessOperands.push_back(spv::IdImmediate(true, builder.makeUintConstant(TranslateMemoryScope(coherentFlags)))); + if (memoryAccess & + (spv::MemoryAccessMakePointerAvailableKHRMask | spv::MemoryAccessMakePointerVisibleKHRMask)) { + memoryAccessOperands.push_back(spv::IdImmediate(true, + builder.makeUintConstant(TranslateMemoryScope(coherentFlags)))); } } else if (arg == 2) { continue; @@ -2805,13 +2977,48 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt } #endif + // for l-values, pass the address, for r-values, pass the value if (lvalue) { - operands.push_back(builder.accessChainGetLValue()); + if (invertedType == spv::NoType && !builder.isSpvLvalue()) { + // SPIR-V cannot represent an l-value containing a swizzle that doesn't + // reduce to a simple access chain. So, we need a temporary vector to + // receive the result, and must later swizzle that into the original + // l-value. + complexLvalues.push_back(builder.getAccessChain()); + temporaryLvalues.push_back(builder.createVariable( + spv::NoPrecision, spv::StorageClassFunction, + builder.accessChainGetInferredType(), "swizzleTemp")); + operands.push_back(temporaryLvalues.back()); + } else { + operands.push_back(builder.accessChainGetLValue()); + } lvalueCoherentFlags = builder.getAccessChain().coherentFlags; lvalueCoherentFlags |= TranslateCoherent(glslangOperands[arg]->getAsTyped()->getType()); } else { builder.setLine(node->getLoc().line, node->getLoc().getFilename()); - operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType())); + glslang::TOperator glslangOp = node->getOp(); + if (arg == 1 && + (glslangOp == glslang::EOpRayQueryGetIntersectionType || + glslangOp == glslang::EOpRayQueryGetIntersectionT || + glslangOp == glslang::EOpRayQueryGetIntersectionInstanceCustomIndex || + glslangOp == glslang::EOpRayQueryGetIntersectionInstanceId || + glslangOp == glslang::EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset || + glslangOp == glslang::EOpRayQueryGetIntersectionGeometryIndex || + glslangOp == glslang::EOpRayQueryGetIntersectionPrimitiveIndex || + glslangOp == glslang::EOpRayQueryGetIntersectionBarycentrics || + glslangOp == glslang::EOpRayQueryGetIntersectionFrontFace || + glslangOp == glslang::EOpRayQueryGetIntersectionObjectRayDirection || + glslangOp == glslang::EOpRayQueryGetIntersectionObjectRayOrigin || + glslangOp == glslang::EOpRayQueryGetIntersectionObjectToWorld || + glslangOp == glslang::EOpRayQueryGetIntersectionWorldToObject + )) { + bool cond = glslangOperands[arg]->getAsConstantUnion()->getConstArray()[0].getBConst(); + operands.push_back(builder.makeIntConstant(cond ? 1 : 0)); + } + else { + operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType())); + } + } } @@ -2847,7 +3054,14 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt #endif if (atomic) { // Handle all atomics - result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(), lvalueCoherentFlags); + result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(), + lvalueCoherentFlags); + } else if (node->getOp() == glslang::EOpDebugPrintf) { + if (!nonSemanticDebugPrintf) { + nonSemanticDebugPrintf = builder.import("NonSemantic.DebugPrintf"); + } + result = builder.createBuiltinCall(builder.makeVoidType(), nonSemanticDebugPrintf, spv::NonSemanticDebugPrintfDebugPrintf, operands); + builder.addExtension(spv::E_SPV_KHR_non_semantic_info); } else { // Pass through to generic operations. switch (glslangOperands.size()) { @@ -2869,8 +3083,14 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt result = createMiscOperation(node->getOp(), precision, resultType(), operands, node->getBasicType()); break; } - if (invertedType) + + if (invertedType != spv::NoResult) result = createInvertedSwizzle(precision, *glslangOperands[0]->getAsBinaryNode(), result); + + for (unsigned int i = 0; i < temporaryLvalues.size(); ++i) { + builder.setAccessChain(complexLvalues[i]); + builder.accessChainStore(builder.createLoad(temporaryLvalues[i], spv::NoPrecision)); + } } if (noReturnValue) @@ -2986,7 +3206,8 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang } else { // We need control flow to select the result. // TODO: Once SPIR-V OpSelect allows arbitrary types, eliminate this path. - result = builder.createVariable(spv::StorageClassFunction, convertGlslangToSpvType(node->getType())); + result = builder.createVariable(TranslatePrecisionDecoration(node->getType()), + spv::StorageClassFunction, convertGlslangToSpvType(node->getType())); // Selection control: const spv::SelectionControlMask control = TranslateSelectionControl(*node); @@ -3011,8 +3232,10 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang // Execute the one side needed, as per the condition const auto executeOneSide = [&]() { // Always emit control flow. - if (node->getBasicType() != glslang::EbtVoid) - result = builder.createVariable(spv::StorageClassFunction, convertGlslangToSpvType(node->getType())); + if (node->getBasicType() != glslang::EbtVoid) { + result = builder.createVariable(TranslatePrecisionDecoration(node->getType()), spv::StorageClassFunction, + convertGlslangToSpvType(node->getType())); + } // Selection control: const spv::SelectionControlMask control = TranslateSelectionControl(*node); @@ -3077,7 +3300,8 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T defaultSegment = (int)codeSegments.size(); else if (child->getAsBranchNode() && child->getAsBranchNode()->getFlowOp() == glslang::EOpCase) { valueIndexToSegment[caseValues.size()] = (int)codeSegments.size(); - caseValues.push_back(child->getAsBranchNode()->getExpression()->getAsConstantUnion()->getConstArray()[0].getIConst()); + caseValues.push_back(child->getAsBranchNode()->getExpression()->getAsConstantUnion() + ->getConstArray()[0].getIConst()); } else codeSegments.push_back(child); } @@ -3090,7 +3314,8 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T // make the switch statement std::vector segmentBlocks; // returned, as the blocks allocated in the call - builder.makeSwitch(selector, control, (int)codeSegments.size(), caseValues, valueIndexToSegment, defaultSegment, segmentBlocks); + builder.makeSwitch(selector, control, (int)codeSegments.size(), caseValues, valueIndexToSegment, defaultSegment, + segmentBlocks); // emit all the code in the segments breakForLoop.push(false); @@ -3207,15 +3432,17 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T builder.createLoopContinue(); break; case glslang::EOpReturn: - if (node->getExpression()) { + if (node->getExpression() != nullptr) { const glslang::TType& glslangReturnType = node->getExpression()->getType(); spv::Id returnId = accessChainLoad(glslangReturnType); - if (builder.getTypeId(returnId) != currentFunction->getReturnType()) { + if (builder.getTypeId(returnId) != currentFunction->getReturnType() || + TranslatePrecisionDecoration(glslangReturnType) != currentFunction->getReturnPrecision()) { builder.clearAccessChain(); - spv::Id copyId = builder.createVariable(spv::StorageClassFunction, currentFunction->getReturnType()); + spv::Id copyId = builder.createVariable(currentFunction->getReturnPrecision(), + spv::StorageClassFunction, currentFunction->getReturnType()); builder.setAccessChainLValue(copyId); multiTypeStore(glslangReturnType, returnId); - returnId = builder.createLoad(copyId); + returnId = builder.createLoad(copyId, currentFunction->getReturnPrecision()); } builder.makeReturn(false, returnId); } else @@ -3311,7 +3538,18 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol* if (glslang::IsAnonymous(name)) name = ""; - return builder.createVariable(storageClass, spvType, name); + spv::Id initializer = spv::NoResult; + + if (node->getType().getQualifier().storage == glslang::EvqUniform && + !node->getConstArray().empty()) { + int nextConst = 0; + initializer = createSpvConstantFromConstUnionArray(node->getType(), + node->getConstArray(), + nextConst, + false /* specConst */); + } + + return builder.createVariable(spv::NoPrecision, storageClass, spvType, name, initializer); } // Return type Id of the sampled type. @@ -3347,7 +3585,8 @@ spv::Id TGlslangToSpvTraverser::getInvertedSwizzleType(const glslang::TIntermTyp // When inverting a swizzle with a parent op, this function // will apply the swizzle operation to a completed parent operation. -spv::Id TGlslangToSpvTraverser::createInvertedSwizzle(spv::Decoration precision, const glslang::TIntermTyped& node, spv::Id parentResult) +spv::Id TGlslangToSpvTraverser::createInvertedSwizzle(spv::Decoration precision, const glslang::TIntermTyped& node, + spv::Id parentResult) { std::vector swizzle; convertSwizzle(*node.getAsBinaryNode()->getRight()->getAsAggregate(), swizzle); @@ -3430,8 +3669,11 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty builder.addCapability(spv::CapabilityAtomicStorage); spvType = builder.makeUintType(32); break; - case glslang::EbtAccStructNV: - spvType = builder.makeAccelerationStructureNVType(); + case glslang::EbtAccStruct: + spvType = builder.makeAccelerationStructureType(); + break; + case glslang::EbtRayQuery: + spvType = builder.makeRayQueryType(); break; case glslang::EbtReference: { @@ -3483,10 +3725,13 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty // else, we haven't seen it... if (type.getBasicType() == glslang::EbtBlock) - memberRemapper[glslangMembers].resize(glslangMembers->size()); + memberRemapper[glslangTypeToIdMap[glslangMembers]].resize(glslangMembers->size()); spvType = convertGlslangStructToSpvType(type, glslangMembers, explicitLayout, qualifier); } break; + case glslang::EbtString: + // no type used for OpString + return 0; default: assert(0); break; @@ -3612,22 +3857,23 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy { // Create a vector of struct types for SPIR-V to consume std::vector spvMembers; - int memberDelta = 0; // how much the member's index changes from glslang to SPIR-V, normally 0, except sometimes for blocks + int memberDelta = 0; // how much the member's index changes from glslang to SPIR-V, normally 0, + // except sometimes for blocks std::vector > deferredForwardPointers; for (int i = 0; i < (int)glslangMembers->size(); i++) { glslang::TType& glslangMember = *(*glslangMembers)[i].type; if (glslangMember.hiddenMember()) { ++memberDelta; if (type.getBasicType() == glslang::EbtBlock) - memberRemapper[glslangMembers][i] = -1; + memberRemapper[glslangTypeToIdMap[glslangMembers]][i] = -1; } else { if (type.getBasicType() == glslang::EbtBlock) { if (filterMember(glslangMember)) { memberDelta++; - memberRemapper[glslangMembers][i] = -1; + memberRemapper[glslangTypeToIdMap[glslangMembers]][i] = -1; continue; } - memberRemapper[glslangMembers][i] = i - memberDelta; + memberRemapper[glslangTypeToIdMap[glslangMembers]][i] = i - memberDelta; } // modify just this child's view of the qualifier glslang::TQualifier memberQualifier = glslangMember.getQualifier(); @@ -3648,10 +3894,12 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy deferredForwardPointers.push_back(std::make_pair(&glslangMember, memberQualifier)); } spvMembers.push_back( - convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember, true)); + convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember, + true)); } else { spvMembers.push_back( - convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember, false)); + convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember, + false)); } } } @@ -3685,7 +3933,7 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, glslang::TType& glslangMember = *(*glslangMembers)[i].type; int member = i; if (type.getBasicType() == glslang::EbtBlock) { - member = memberRemapper[glslangMembers][i]; + member = memberRemapper[glslangTypeToIdMap[glslangMembers]][i]; if (filterMember(glslangMember)) continue; } @@ -3839,11 +4087,11 @@ spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type) alignment |= type.getBufferReferenceAlignment(); spv::Id loadedId = builder.accessChainLoad(TranslatePrecisionDecoration(type), - TranslateNonUniformDecoration(type.getQualifier()), - nominalTypeId, - spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerAvailableKHRMask), - TranslateMemoryScope(coherentFlags), - alignment); + TranslateNonUniformDecoration(type.getQualifier()), + nominalTypeId, + spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerAvailableKHRMask), + TranslateMemoryScope(coherentFlags), + alignment); // Need to convert to abstract types when necessary if (type.getBasicType() == glslang::EbtBool) { @@ -3857,7 +4105,8 @@ spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type) int vecSize = builder.getNumTypeComponents(nominalTypeId); spv::Id bvecType = builder.makeVectorType(builder.makeBoolType(), vecSize); if (nominalTypeId != bvecType) - loadedId = builder.createBinOp(spv::OpINotEqual, bvecType, loadedId, makeSmearedConstant(builder.makeUintConstant(0), vecSize)); + loadedId = builder.createBinOp(spv::OpINotEqual, bvecType, loadedId, + makeSmearedConstant(builder.makeUintConstant(0), vecSize)); } } @@ -3906,7 +4155,8 @@ void TGlslangToSpvTraverser::accessChainStore(const glslang::TType& type, spv::I alignment |= type.getBufferReferenceAlignment(); builder.accessChainStore(rvalue, - spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerVisibleKHRMask), + spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & + ~spv::MemoryAccessMakePointerVisibleKHRMask), TranslateMemoryScope(coherentFlags), alignment); } @@ -3967,7 +4217,8 @@ void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id // set up the target storage builder.clearAccessChain(); builder.setAccessChainLValue(lValue); - builder.accessChainPush(builder.makeIntConstant(index), TranslateCoherent(type), type.getBufferReferenceAlignment()); + builder.accessChainPush(builder.makeIntConstant(index), TranslateCoherent(type), + type.getBufferReferenceAlignment()); // store the member multiTypeStore(glslangElementType, elementRValue); @@ -3987,7 +4238,8 @@ void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id // set up the target storage builder.clearAccessChain(); builder.setAccessChainLValue(lValue); - builder.accessChainPush(builder.makeIntConstant(m), TranslateCoherent(type), type.getBufferReferenceAlignment()); + builder.accessChainPush(builder.makeIntConstant(m), TranslateCoherent(type), + type.getBufferReferenceAlignment()); // store the member multiTypeStore(glslangMemberType, memberRValue); @@ -4022,18 +4274,21 @@ glslang::TLayoutPacking TGlslangToSpvTraverser::getExplicitLayout(const glslang: } // Given an array type, returns the integer stride required for that array -int TGlslangToSpvTraverser::getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout) +int TGlslangToSpvTraverser::getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking explicitLayout, + glslang::TLayoutMatrix matrixLayout) { int size; int stride; - glslangIntermediate->getMemberAlignment(arrayType, size, stride, explicitLayout, matrixLayout == glslang::ElmRowMajor); + glslangIntermediate->getMemberAlignment(arrayType, size, stride, explicitLayout, + matrixLayout == glslang::ElmRowMajor); return stride; } // Given a matrix type, or array (of array) of matrixes type, returns the integer stride required for that matrix // when used as a member of an interface block -int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout) +int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking explicitLayout, + glslang::TLayoutMatrix matrixLayout) { glslang::TType elementType; elementType.shallowCopy(matrixType); @@ -4041,7 +4296,8 @@ int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType, gl int size; int stride; - glslangIntermediate->getMemberAlignment(elementType, size, stride, explicitLayout, matrixLayout == glslang::ElmRowMajor); + glslangIntermediate->getMemberAlignment(elementType, size, stride, explicitLayout, + matrixLayout == glslang::ElmRowMajor); return stride; } @@ -4052,8 +4308,8 @@ int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType, gl // 'currentOffset' should be passed in already initialized, ready to modify, and reflecting // the migration of data from nextOffset -> currentOffset. It should be -1 on the first call. // -1 means a non-forced member offset (no decoration needed). -void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType, int& currentOffset, int& nextOffset, - glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout) +void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType, + int& currentOffset, int& nextOffset, glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout) { // this will get a positive value when deemed necessary nextOffset = -1; @@ -4083,7 +4339,8 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType int memberSize; int dummyStride; - int memberAlignment = glslangIntermediate->getMemberAlignment(memberType, memberSize, dummyStride, explicitLayout, matrixLayout == glslang::ElmRowMajor); + int memberAlignment = glslangIntermediate->getMemberAlignment(memberType, memberSize, dummyStride, explicitLayout, + matrixLayout == glslang::ElmRowMajor); // Adjust alignment for HLSL rules // TODO: make this consistent in early phases of code: @@ -4102,7 +4359,8 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType glslang::RoundToPow2(currentOffset, memberAlignment); // Bump up to vec4 if there is a bad straddle - if (explicitLayout != glslang::ElpScalar && glslangIntermediate->improperStraddle(memberType, memberSize, currentOffset)) + if (explicitLayout != glslang::ElpScalar && glslangIntermediate->improperStraddle(memberType, memberSize, + currentOffset)) glslang::RoundToPow2(currentOffset, 16); nextOffset = currentOffset + memberSize; @@ -4155,8 +4413,10 @@ bool TGlslangToSpvTraverser::writableParam(glslang::TStorageQualifier qualifier) assert(qualifier == glslang::EvqIn || qualifier == glslang::EvqOut || qualifier == glslang::EvqInOut || + qualifier == glslang::EvqUniform || qualifier == glslang::EvqConstReadOnly); - return qualifier != glslang::EvqConstReadOnly; + return qualifier != glslang::EvqConstReadOnly && + qualifier != glslang::EvqUniform; } // Is parameter pass-by-original? @@ -4174,7 +4434,8 @@ bool TGlslangToSpvTraverser::originalParam(glslang::TStorageQualifier qualifier, // Make all the functions, skeletally, without actually visiting their bodies. void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslFunctions) { - const auto getParamDecorations = [&](std::vector& decorations, const glslang::TType& type, bool useVulkanMemoryModel) { + const auto getParamDecorations = [&](std::vector& decorations, const glslang::TType& type, + bool useVulkanMemoryModel) { spv::Decoration paramPrecision = TranslatePrecisionDecoration(type); if (paramPrecision != spv::NoPrecision) decorations.push_back(paramPrecision); @@ -4272,7 +4533,8 @@ void TGlslangToSpvTraverser::makeGlobalInitializers(const glslang::TIntermSequen builder.setBuildPoint(shaderEntry->getLastBlock()); for (int i = 0; i < (int)initializers.size(); ++i) { glslang::TIntermAggregate* initializer = initializers[i]->getAsAggregate(); - if (initializer && initializer->getOp() != glslang::EOpFunction && initializer->getOp() != glslang::EOpLinkerObjects) { + if (initializer && initializer->getOp() != glslang::EOpFunction && initializer->getOp() != + glslang::EOpLinkerObjects) { // We're on a top-level node that's not a function. Treat as an initializer, whose // code goes into the beginning of the entry point. @@ -4300,7 +4562,8 @@ void TGlslangToSpvTraverser::handleFunctionEntry(const glslang::TIntermAggregate builder.setBuildPoint(functionBlock); } -void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& node, std::vector& arguments, spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags) +void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& node, std::vector& arguments, + spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags) { const glslang::TIntermSequence& glslangArguments = node.getSequence(); @@ -4313,7 +4576,8 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& sampler = glslangArguments[0]->getAsTyped()->getType().getSampler(); cubeCompare = sampler.dim == glslang::EsdCube && sampler.arrayed && sampler.shadow; #ifndef GLSLANG_WEB - f16ShadowCompare = sampler.shadow && glslangArguments[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16; + f16ShadowCompare = sampler.shadow && + glslangArguments[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16; #endif } @@ -4476,7 +4740,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO translateArguments(*node->getAsAggregate(), arguments, lvalueCoherentFlags); else translateArguments(*node->getAsUnaryNode(), arguments); - spv::Decoration precision = TranslatePrecisionDecoration(node->getOperationPrecision()); + spv::Decoration precision = TranslatePrecisionDecoration(node->getType()); spv::Builder::TextureParameters params = { }; params.sampler = arguments[0]; @@ -4689,7 +4953,8 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO operands.push_back(imageOperand); } if (mask & spv::ImageOperandsMakeTexelVisibleKHRMask) { - spv::IdImmediate imageOperand = { true, builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) }; + spv::IdImmediate imageOperand = { true, builder.makeUintConstant(TranslateMemoryScope( + TranslateCoherent(imageType))) }; operands.push_back(imageOperand); } @@ -4717,18 +4982,22 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO // imageAtomicStore has a void return type so base the pointer type on // the type of the value operand. if (node->getOp() == glslang::EOpImageAtomicStore) { - resultTypeId = builder.makePointer(spv::StorageClassImage, builder.getTypeId(operands[2].word)); + resultTypeId = builder.makePointer(spv::StorageClassImage, builder.getTypeId(*opIt)); } else { resultTypeId = builder.makePointer(spv::StorageClassImage, resultType()); } spv::Id pointer = builder.createOp(spv::OpImageTexelPointer, resultTypeId, operands); + if (imageType.getQualifier().nonUniform) { + builder.addDecoration(pointer, spv::DecorationNonUniformEXT); + } std::vector operands; operands.push_back(pointer); for (; opIt != arguments.end(); ++opIt) operands.push_back(*opIt); - return createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(), lvalueCoherentFlags); + return createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(), + lvalueCoherentFlags); } } @@ -4753,7 +5022,8 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO std::vector comps; comps.push_back(zero); comps.push_back(zero); - operands.push_back(builder.makeCompositeConstant(builder.makeVectorType(builder.makeIntType(32), 2), comps)); + operands.push_back(builder.makeCompositeConstant( + builder.makeVectorType(builder.makeIntType(32), 2), comps)); } for (; opIt != arguments.end(); ++opIt) @@ -4842,7 +5112,8 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO else dRefComp = builder.getNumComponents(params.coords) - 1; indexes.push_back(dRefComp); - params.Dref = builder.createCompositeExtract(params.coords, builder.getScalarTypeId(builder.getTypeId(params.coords)), indexes); + params.Dref = builder.createCompositeExtract(params.coords, + builder.getScalarTypeId(builder.getTypeId(params.coords)), indexes); } // lod @@ -4967,7 +5238,8 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO flags.clear(); builder.accessChainPush(builder.makeIntConstant(i), flags, 0); - builder.accessChainStore(builder.createCompositeExtract(res, builder.getContainedTypeId(resType, i+1), i+1)); + builder.accessChainStore(builder.createCompositeExtract(res, builder.getContainedTypeId(resType, i+1), + i+1)); } return builder.createCompositeExtract(res, resultType(), 0); } @@ -4990,10 +5262,9 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO // copy the projective coordinate if we have to if (projTargetComp != projSourceComp) { spv::Id projComp = builder.createCompositeExtract(params.coords, - builder.getScalarTypeId(builder.getTypeId(params.coords)), - projSourceComp); + builder.getScalarTypeId(builder.getTypeId(params.coords)), projSourceComp); params.coords = builder.createCompositeInsert(projComp, params.coords, - builder.getTypeId(params.coords), projTargetComp); + builder.getTypeId(params.coords), projTargetComp); } } @@ -5073,7 +5344,8 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg ++lValueCount; } else if (writableParam(qualifiers[a])) { // need space to hold the copy - arg = builder.createVariable(spv::StorageClassFunction, builder.getContainedTypeId(function->getParamType(a)), "param"); + arg = builder.createVariable(function->getParamPrecision(a), spv::StorageClassFunction, + builder.getContainedTypeId(function->getParamType(a)), "param"); if (qualifiers[a] == glslang::EvqIn || qualifiers[a] == glslang::EvqInOut) { // need to copy the input into output space builder.setAccessChain(lValues[lValueCount]); @@ -5085,12 +5357,14 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg ++lValueCount; } else { // process r-value, which involves a copy for a type mismatch - if (function->getParamType(a) != convertGlslangToSpvType(*argTypes[a])) { - spv::Id argCopy = builder.createVariable(spv::StorageClassFunction, function->getParamType(a), "arg"); + if (function->getParamType(a) != convertGlslangToSpvType(*argTypes[a]) || + TranslatePrecisionDecoration(*argTypes[a]) != function->getParamPrecision(a)) + { + spv::Id argCopy = builder.createVariable(function->getParamPrecision(a), spv::StorageClassFunction, function->getParamType(a), "arg"); builder.clearAccessChain(); builder.setAccessChainLValue(argCopy); multiTypeStore(*argTypes[a], rValues[rValueCount]); - arg = builder.createLoad(argCopy); + arg = builder.createLoad(argCopy, function->getParamPrecision(a)); } else arg = rValues[rValueCount]; ++rValueCount; @@ -5109,7 +5383,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg ++lValueCount; else if (writableParam(qualifiers[a])) { if (qualifiers[a] == glslang::EvqOut || qualifiers[a] == glslang::EvqInOut) { - spv::Id copy = builder.createLoad(spvArgs[a]); + spv::Id copy = builder.createLoad(spvArgs[a], spv::NoPrecision); builder.setAccessChain(lValues[lValueCount]); multiTypeStore(*argTypes[a], copy); } @@ -5354,7 +5628,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD case glslang::EOpNotEqual: case glslang::EOpVectorNotEqual: if (isFloat) - binOp = spv::OpFOrdNotEqual; + binOp = spv::OpFUnordNotEqual; else if (isBool) binOp = spv::OpLogicalNotEqual; else @@ -5488,7 +5762,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, OpDecora } spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDecorations& decorations, spv::Id typeId, - spv::Id operand, glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags) + spv::Id operand, glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags) { spv::Op unaryOp = spv::OpNop; int extBuiltins = -1; @@ -5749,6 +6023,24 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe case glslang::EOpFwidthCoarse: unaryOp = spv::OpFwidthCoarse; break; + case glslang::EOpRayQueryProceed: + unaryOp = spv::OpRayQueryProceedKHR; + break; + case glslang::EOpRayQueryGetRayTMin: + unaryOp = spv::OpRayQueryGetRayTMinKHR; + break; + case glslang::EOpRayQueryGetRayFlags: + unaryOp = spv::OpRayQueryGetRayFlagsKHR; + break; + case glslang::EOpRayQueryGetWorldRayOrigin: + unaryOp = spv::OpRayQueryGetWorldRayOriginKHR; + break; + case glslang::EOpRayQueryGetWorldRayDirection: + unaryOp = spv::OpRayQueryGetWorldRayDirectionKHR; + break; + case glslang::EOpRayQueryGetIntersectionCandidateAABBOpaque: + unaryOp = spv::OpRayQueryGetIntersectionCandidateAABBOpaqueKHR; + break; case glslang::EOpInterpolateAtCentroid: if (typeProxy == glslang::EbtFloat16) builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float); @@ -6034,7 +6326,7 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora case glslang::EOpConvFloatToBool: zero = builder.makeFloatConstant(0.0F); zero = makeSmearedConstant(zero, vectorSize); - return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero); + return builder.createBinOp(spv::OpFUnordNotEqual, destType, operand, zero); case glslang::EOpConvBoolToFloat: convOp = spv::OpSelect; zero = builder.makeFloatConstant(0.0F); @@ -6183,11 +6475,11 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora case glslang::EOpConvDoubleToBool: zero = builder.makeDoubleConstant(0.0); zero = makeSmearedConstant(zero, vectorSize); - return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero); + return builder.createBinOp(spv::OpFUnordNotEqual, destType, operand, zero); case glslang::EOpConvFloat16ToBool: zero = builder.makeFloat16Constant(0.0F); zero = makeSmearedConstant(zero, vectorSize); - return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero); + return builder.createBinOp(spv::OpFUnordNotEqual, destType, operand, zero); case glslang::EOpConvBoolToDouble: convOp = spv::OpSelect; zero = builder.makeDoubleConstant(0.0); @@ -6381,7 +6673,9 @@ spv::Id TGlslangToSpvTraverser::makeSmearedConstant(spv::Id constant, int vector } // For glslang ops that map to SPV atomic opCodes -spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv::Decoration /*precision*/, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags) +spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv::Decoration /*precision*/, + spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy, + const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags) { spv::Op opCode = spv::OpNop; @@ -6390,6 +6684,14 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv case glslang::EOpImageAtomicAdd: case glslang::EOpAtomicCounterAdd: opCode = spv::OpAtomicIAdd; + if (typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) { + opCode = spv::OpAtomicFAddEXT; + builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_add); + if (typeProxy == glslang::EbtFloat) + builder.addCapability(spv::CapabilityAtomicFloat32AddEXT); + else + builder.addCapability(spv::CapabilityAtomicFloat64AddEXT); + } break; case glslang::EOpAtomicCounterSubtract: opCode = spv::OpAtomicISub; @@ -6397,12 +6699,14 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv case glslang::EOpAtomicMin: case glslang::EOpImageAtomicMin: case glslang::EOpAtomicCounterMin: - opCode = (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) ? spv::OpAtomicUMin : spv::OpAtomicSMin; + opCode = (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) ? + spv::OpAtomicUMin : spv::OpAtomicSMin; break; case glslang::EOpAtomicMax: case glslang::EOpImageAtomicMax: case glslang::EOpAtomicCounterMax: - opCode = (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) ? spv::OpAtomicUMax : spv::OpAtomicSMax; + opCode = (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) ? + spv::OpAtomicUMax : spv::OpAtomicSMax; break; case glslang::EOpAtomicAnd: case glslang::EOpImageAtomicAnd: @@ -6467,7 +6771,8 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv scopeId = builder.makeUintConstant(spv::ScopeDevice); } // semantics default to relaxed - spv::Id semanticsId = builder.makeUintConstant(lvalueCoherentFlags.isVolatile() && glslangIntermediate->usingVulkanMemoryModel() ? + spv::Id semanticsId = builder.makeUintConstant(lvalueCoherentFlags.isVolatile() && + glslangIntermediate->usingVulkanMemoryModel() ? spv::MemorySemanticsVolatileMask : spv::MemorySemanticsMaskNone); spv::Id semanticsId2 = semanticsId; @@ -6480,20 +6785,24 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv valueId = operands[2]; if (operands.size() > 3) { scopeId = operands[3]; - semanticsId = builder.makeUintConstant(builder.getConstantScalar(operands[4]) | builder.getConstantScalar(operands[5])); - semanticsId2 = builder.makeUintConstant(builder.getConstantScalar(operands[6]) | builder.getConstantScalar(operands[7])); + semanticsId = builder.makeUintConstant( + builder.getConstantScalar(operands[4]) | builder.getConstantScalar(operands[5])); + semanticsId2 = builder.makeUintConstant( + builder.getConstantScalar(operands[6]) | builder.getConstantScalar(operands[7])); } } else if (opCode == spv::OpAtomicLoad) { if (operands.size() > 1) { scopeId = operands[1]; - semanticsId = builder.makeUintConstant(builder.getConstantScalar(operands[2]) | builder.getConstantScalar(operands[3])); + semanticsId = builder.makeUintConstant( + builder.getConstantScalar(operands[2]) | builder.getConstantScalar(operands[3])); } } else { // atomic store or RMW valueId = operands[1]; if (operands.size() > 2) { scopeId = operands[2]; - semanticsId = builder.makeUintConstant(builder.getConstantScalar(operands[3]) | builder.getConstantScalar(operands[4])); + semanticsId = builder.makeUintConstant + (builder.getConstantScalar(operands[3]) | builder.getConstantScalar(operands[4])); } } @@ -6538,7 +6847,8 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv } // Create group invocation operations. -spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy) +spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op, spv::Id typeId, + std::vector& operands, glslang::TBasicType typeProxy) { bool isUnsigned = isTypeUnsignedInt(typeProxy); bool isFloat = isTypeFloat(typeProxy); @@ -6752,8 +7062,10 @@ spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv op == spv::OpGroupFMax || op == spv::OpGroupUMax || op == spv::OpGroupSMax || op == spv::OpGroupFAdd || op == spv::OpGroupIAdd || op == spv::OpGroupBroadcast || op == spv::OpSubgroupReadInvocationKHR || - op == spv::OpGroupFMinNonUniformAMD || op == spv::OpGroupUMinNonUniformAMD || op == spv::OpGroupSMinNonUniformAMD || - op == spv::OpGroupFMaxNonUniformAMD || op == spv::OpGroupUMaxNonUniformAMD || op == spv::OpGroupSMaxNonUniformAMD || + op == spv::OpGroupFMinNonUniformAMD || op == spv::OpGroupUMinNonUniformAMD || + op == spv::OpGroupSMinNonUniformAMD || + op == spv::OpGroupFMaxNonUniformAMD || op == spv::OpGroupUMaxNonUniformAMD || + op == spv::OpGroupSMaxNonUniformAMD || op == spv::OpGroupFAddNonUniformAMD || op == spv::OpGroupIAddNonUniformAMD); // Handle group invocation operations scalar by scalar. @@ -7142,7 +7454,8 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s return builder.createOp(opCode, typeId, spvGroupOperands); } -spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy) +spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::Decoration precision, + spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy) { bool isUnsigned = isTypeUnsignedInt(typeProxy); bool isFloat = isTypeFloat(typeProxy); @@ -7244,14 +7557,16 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: unsigned int executionScope = builder.getConstantScalar(operands[0]); unsigned int memoryScope = builder.getConstantScalar(operands[1]); unsigned int semantics = builder.getConstantScalar(operands[2]) | builder.getConstantScalar(operands[3]); - builder.createControlBarrier((spv::Scope)executionScope, (spv::Scope)memoryScope, (spv::MemorySemanticsMask)semantics); + builder.createControlBarrier((spv::Scope)executionScope, (spv::Scope)memoryScope, + (spv::MemorySemanticsMask)semantics); if (semantics & (spv::MemorySemanticsMakeAvailableKHRMask | spv::MemorySemanticsMakeVisibleKHRMask | spv::MemorySemanticsOutputMemoryKHRMask | spv::MemorySemanticsVolatileMask)) { builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); } - if (glslangIntermediate->usingVulkanMemoryModel() && (executionScope == spv::ScopeDevice || memoryScope == spv::ScopeDevice)) { + if (glslangIntermediate->usingVulkanMemoryModel() && (executionScope == spv::ScopeDevice || + memoryScope == spv::ScopeDevice)) { builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR); } return 0; @@ -7334,7 +7649,8 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: if (builder.getNumComponents(operands[0]) == 1) frexpIntType = builder.makeIntegerType(width, true); else - frexpIntType = builder.makeVectorType(builder.makeIntegerType(width, true), builder.getNumComponents(operands[0])); + frexpIntType = builder.makeVectorType(builder.makeIntegerType(width, true), + builder.getNumComponents(operands[0])); typeId = builder.makeStructResultType(typeId0, frexpIntType); consumedOperands = 1; } @@ -7437,24 +7753,105 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: libCall = spv::InterpolateAtVertexAMD; break; - case glslang::EOpReportIntersectionNV: - { + case glslang::EOpReportIntersection: typeId = builder.makeBoolType(); - opCode = spv::OpReportIntersectionNV; - } - break; - case glslang::EOpTraceNV: - { - builder.createNoResultOp(spv::OpTraceNV, operands); + opCode = spv::OpReportIntersectionKHR; + break; + case glslang::EOpTrace: + builder.createNoResultOp(spv::OpTraceRayKHR, operands); return 0; - } - break; - case glslang::EOpExecuteCallableNV: - { - builder.createNoResultOp(spv::OpExecuteCallableNV, operands); + case glslang::EOpExecuteCallable: + builder.createNoResultOp(spv::OpExecuteCallableKHR, operands); return 0; - } - break; + + case glslang::EOpRayQueryInitialize: + builder.createNoResultOp(spv::OpRayQueryInitializeKHR, operands); + return 0; + case glslang::EOpRayQueryTerminate: + builder.createNoResultOp(spv::OpRayQueryTerminateKHR, operands); + return 0; + case glslang::EOpRayQueryGenerateIntersection: + builder.createNoResultOp(spv::OpRayQueryGenerateIntersectionKHR, operands); + return 0; + case glslang::EOpRayQueryConfirmIntersection: + builder.createNoResultOp(spv::OpRayQueryConfirmIntersectionKHR, operands); + return 0; + case glslang::EOpRayQueryProceed: + typeId = builder.makeBoolType(); + opCode = spv::OpRayQueryProceedKHR; + break; + case glslang::EOpRayQueryGetIntersectionType: + typeId = builder.makeUintType(32); + opCode = spv::OpRayQueryGetIntersectionTypeKHR; + break; + case glslang::EOpRayQueryGetRayTMin: + typeId = builder.makeFloatType(32); + opCode = spv::OpRayQueryGetRayTMinKHR; + break; + case glslang::EOpRayQueryGetRayFlags: + typeId = builder.makeIntType(32); + opCode = spv::OpRayQueryGetRayFlagsKHR; + break; + case glslang::EOpRayQueryGetIntersectionT: + typeId = builder.makeFloatType(32); + opCode = spv::OpRayQueryGetIntersectionTKHR; + break; + case glslang::EOpRayQueryGetIntersectionInstanceCustomIndex: + typeId = builder.makeIntType(32); + opCode = spv::OpRayQueryGetIntersectionInstanceCustomIndexKHR; + break; + case glslang::EOpRayQueryGetIntersectionInstanceId: + typeId = builder.makeIntType(32); + opCode = spv::OpRayQueryGetIntersectionInstanceIdKHR; + break; + case glslang::EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset: + typeId = builder.makeIntType(32); + opCode = spv::OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR; + break; + case glslang::EOpRayQueryGetIntersectionGeometryIndex: + typeId = builder.makeIntType(32); + opCode = spv::OpRayQueryGetIntersectionGeometryIndexKHR; + break; + case glslang::EOpRayQueryGetIntersectionPrimitiveIndex: + typeId = builder.makeIntType(32); + opCode = spv::OpRayQueryGetIntersectionPrimitiveIndexKHR; + break; + case glslang::EOpRayQueryGetIntersectionBarycentrics: + typeId = builder.makeVectorType(builder.makeFloatType(32), 2); + opCode = spv::OpRayQueryGetIntersectionBarycentricsKHR; + break; + case glslang::EOpRayQueryGetIntersectionFrontFace: + typeId = builder.makeBoolType(); + opCode = spv::OpRayQueryGetIntersectionFrontFaceKHR; + break; + case glslang::EOpRayQueryGetIntersectionCandidateAABBOpaque: + typeId = builder.makeBoolType(); + opCode = spv::OpRayQueryGetIntersectionCandidateAABBOpaqueKHR; + break; + case glslang::EOpRayQueryGetIntersectionObjectRayDirection: + typeId = builder.makeVectorType(builder.makeFloatType(32), 3); + opCode = spv::OpRayQueryGetIntersectionObjectRayDirectionKHR; + break; + case glslang::EOpRayQueryGetIntersectionObjectRayOrigin: + typeId = builder.makeVectorType(builder.makeFloatType(32), 3); + opCode = spv::OpRayQueryGetIntersectionObjectRayOriginKHR; + break; + case glslang::EOpRayQueryGetWorldRayDirection: + typeId = builder.makeVectorType(builder.makeFloatType(32), 3); + opCode = spv::OpRayQueryGetWorldRayDirectionKHR; + break; + case glslang::EOpRayQueryGetWorldRayOrigin: + typeId = builder.makeVectorType(builder.makeFloatType(32), 3); + opCode = spv::OpRayQueryGetWorldRayOriginKHR; + break; + case glslang::EOpRayQueryGetIntersectionObjectToWorld: + typeId = builder.makeMatrixType(builder.makeFloatType(32), 4, 3); + opCode = spv::OpRayQueryGetIntersectionObjectToWorldKHR; + break; + case glslang::EOpRayQueryGetIntersectionWorldToObject: + typeId = builder.makeMatrixType(builder.makeFloatType(32), 4, 3); + opCode = spv::OpRayQueryGetIntersectionWorldToObjectKHR; + break; case glslang::EOpWritePackedPrimitiveIndices4x8NV: builder.createNoResultOp(spv::OpWritePackedPrimitiveIndices4x8NV, operands); return 0; @@ -7544,7 +7941,8 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId) { // GLSL memory barriers use queuefamily scope in new model, device scope in old model - spv::Scope memoryBarrierScope = glslangIntermediate->usingVulkanMemoryModel() ? spv::ScopeQueueFamilyKHR : spv::ScopeDevice; + spv::Scope memoryBarrierScope = glslangIntermediate->usingVulkanMemoryModel() ? + spv::ScopeQueueFamilyKHR : spv::ScopeDevice; switch (op) { case glslang::EOpBarrier: @@ -7650,13 +8048,24 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv: spv::Id id = builder.createBuiltinCall(typeId, getExtBuiltins(spv::E_SPV_AMD_gcn_shader), spv::TimeAMD, args); return builder.setPrecision(id, precision); } - case glslang::EOpIgnoreIntersectionNV: - builder.createNoResultOp(spv::OpIgnoreIntersectionNV); + case glslang::EOpIgnoreIntersection: + builder.createNoResultOp(spv::OpIgnoreIntersectionKHR); return 0; - case glslang::EOpTerminateRayNV: - builder.createNoResultOp(spv::OpTerminateRayNV); + case glslang::EOpTerminateRay: + builder.createNoResultOp(spv::OpTerminateRayKHR); + return 0; + case glslang::EOpRayQueryInitialize: + builder.createNoResultOp(spv::OpRayQueryInitializeKHR); + return 0; + case glslang::EOpRayQueryTerminate: + builder.createNoResultOp(spv::OpRayQueryTerminateKHR); + return 0; + case glslang::EOpRayQueryGenerateIntersection: + builder.createNoResultOp(spv::OpRayQueryGenerateIntersectionKHR); + return 0; + case glslang::EOpRayQueryConfirmIntersection: + builder.createNoResultOp(spv::OpRayQueryConfirmIntersectionKHR); return 0; - case glslang::EOpBeginInvocationInterlock: builder.createNoResultOp(spv::OpBeginInvocationInterlockEXT); return 0; @@ -7708,7 +8117,7 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol // it was not found, create it spv::BuiltIn builtIn = TranslateBuiltInDecoration(symbol->getQualifier().builtIn, false); - auto forcedType = getForcedType(builtIn, symbol->getType()); + auto forcedType = getForcedType(symbol->getQualifier().builtIn, symbol->getType()); id = createSpvVariable(symbol, forcedType.first); symbolValues[symbol->getId()] = id; if (forcedType.second != spv::NoType) @@ -7773,7 +8182,8 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol #ifndef GLSLANG_WEB if (symbol->getType().isImage()) { std::vector memory; - TranslateMemoryDecoration(symbol->getType().getQualifier(), memory, glslangIntermediate->usingVulkanMemoryModel()); + TranslateMemoryDecoration(symbol->getType().getQualifier(), memory, + glslangIntermediate->usingVulkanMemoryModel()); for (unsigned int i = 0; i < memory.size(); ++i) builder.addDecoration(id, memory[i]); } @@ -7827,7 +8237,8 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol } if (symbol->isReference()) { - builder.addDecoration(id, symbol->getType().getQualifier().restrict ? spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT); + builder.addDecoration(id, symbol->getType().getQualifier().restrict ? + spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT); } #endif @@ -7889,12 +8300,25 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TIntermTyped& n // hand off to the non-spec-constant path assert(node.getAsConstantUnion() != nullptr || node.getAsSymbolNode() != nullptr); int nextConst = 0; - return createSpvConstantFromConstUnionArray(node.getType(), node.getAsConstantUnion() ? node.getAsConstantUnion()->getConstArray() : node.getAsSymbolNode()->getConstArray(), - nextConst, false); + return createSpvConstantFromConstUnionArray(node.getType(), node.getAsConstantUnion() ? + node.getAsConstantUnion()->getConstArray() : node.getAsSymbolNode()->getConstArray(), + nextConst, false); } // We now know we have a specialization constant to build + // Extra capabilities may be needed. + if (node.getType().contains8BitInt()) + builder.addCapability(spv::CapabilityInt8); + if (node.getType().contains16BitFloat()) + builder.addCapability(spv::CapabilityFloat16); + if (node.getType().contains16BitInt()) + builder.addCapability(spv::CapabilityInt16); + if (node.getType().contains64BitInt()) + builder.addCapability(spv::CapabilityInt64); + if (node.getType().containsDouble()) + builder.addCapability(spv::CapabilityFloat64); + // gl_WorkGroupSize is a special case until the front-end handles hierarchical specialization constants, // even then, it's specialization ids are handled by special case syntax in GLSL: layout(local_size_x = ... if (node.getType().getQualifier().builtIn == glslang::EbvWorkGroupSize) { @@ -7943,7 +8367,8 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TIntermTyped& n // If there are not enough elements present in 'consts', 0 will be substituted; // an empty 'consts' can be used to create a fully zeroed SPIR-V constant. // -spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glslang::TType& glslangType, const glslang::TConstUnionArray& consts, int& nextConst, bool specConstant) +spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glslang::TType& glslangType, + const glslang::TConstUnionArray& consts, int& nextConst, bool specConstant) { // vector of constants for SPIR-V std::vector spvConsts; @@ -8061,6 +8486,9 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla scalar = builder.createUnaryOp(spv::OpBitcast, typeId, scalar); break; #endif + case glslang::EbtString: + scalar = builder.getStringId(consts[nextConst].getSConst()->c_str()); + break; default: assert(0); break; @@ -8161,7 +8589,8 @@ bool TGlslangToSpvTraverser::isTrivial(const glslang::TIntermTyped* node) // Emit short-circuiting code, where 'right' is never evaluated unless // the left side is true (for &&) or false (for ||). -spv::Id TGlslangToSpvTraverser::createShortCircuit(glslang::TOperator op, glslang::TIntermTyped& left, glslang::TIntermTyped& right) +spv::Id TGlslangToSpvTraverser::createShortCircuit(glslang::TOperator op, glslang::TIntermTyped& left, + glslang::TIntermTyped& right) { spv::Id boolTypeId = builder.makeBoolType(); @@ -8245,7 +8674,9 @@ int GetSpirvGeneratorVersion() // return 6; // revert version 5 change, which makes a different (new) kind of incorrect code, // versions 4 and 6 each generate OpArrayLength as it has long been done // return 7; // GLSL volatile keyword maps to both SPIR-V decorations Volatile and Coherent - return 8; // switch to new dead block eliminator; use OpUnreachable + // return 8; // switch to new dead block eliminator; use OpUnreachable + // return 9; // don't include opaque function parameters in OpEntryPoint global's operand list + return 10; // Generate OpFUnordNotEqual for != comparisons } // Write SPIR-V out to a binary file @@ -8265,14 +8696,15 @@ void OutputSpvBin(const std::vector& spirv, const char* baseName) // Write SPIR-V out to a text file with 32-bit hexadecimal words void OutputSpvHex(const std::vector& spirv, const char* baseName, const char* varName) { -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) std::ofstream out; out.open(baseName, std::ios::binary | std::ios::out); if (out.fail()) printf("ERROR: Failed to open file: %s\n", baseName); - out << "\t// " << - GetSpirvGeneratorVersion() << "." << GLSLANG_MINOR_VERSION << "." << GLSLANG_PATCH_LEVEL << - std::endl; + out << "\t// " << + GetSpirvGeneratorVersion() << + GLSLANG_VERSION_MAJOR << "." << GLSLANG_VERSION_MINOR << "." << GLSLANG_VERSION_PATCH << + GLSLANG_VERSION_FLAVOR << std::endl; if (varName != nullptr) { out << "\t #pragma once" << std::endl; out << "const uint32_t " << varName << "[] = {" << std::endl; @@ -8291,6 +8723,7 @@ void OutputSpvHex(const std::vector& spirv, const char* baseName, } if (varName != nullptr) { out << "};"; + out << std::endl; } out.close(); #endif @@ -8328,10 +8761,14 @@ void GlslangToSpv(const TIntermediate& intermediate, std::vector& // If from HLSL, run spirv-opt to "legalize" the SPIR-V for Vulkan // eg. forward and remove memory writes of opaque types. bool prelegalization = intermediate.getSource() == EShSourceHlsl; - if ((intermediate.getSource() == EShSourceHlsl || options->optimizeSize) && !options->disableOptimizer) { - SpirvToolsLegalize(intermediate, spirv, logger, options); + if ((prelegalization || options->optimizeSize) && !options->disableOptimizer) { + SpirvToolsTransform(intermediate, spirv, logger, options); prelegalization = false; } + else if (options->stripDebugInfo) { + // Strip debug info even if optimization is disabled. + SpirvToolsStripDebugInfo(intermediate, spirv, logger); + } if (options->validate) SpirvToolsValidate(intermediate, spirv, logger, prelegalization); diff --git a/src/libraries/glslang/SPIRV/GlslangToSpv.h b/src/libraries/glslang/SPIRV/GlslangToSpv.h old mode 100755 new mode 100644 diff --git a/src/libraries/glslang/SPIRV/Logger.cpp b/src/libraries/glslang/SPIRV/Logger.cpp index 7ea0c6342..cdc8469c4 100644 --- a/src/libraries/glslang/SPIRV/Logger.cpp +++ b/src/libraries/glslang/SPIRV/Logger.cpp @@ -69,4 +69,4 @@ std::string SpvBuildLogger::getAllMessages() const { } // end spv namespace -#endif \ No newline at end of file +#endif diff --git a/src/libraries/glslang/SPIRV/NonSemanticDebugPrintf.h b/src/libraries/glslang/SPIRV/NonSemanticDebugPrintf.h new file mode 100644 index 000000000..83796d75e --- /dev/null +++ b/src/libraries/glslang/SPIRV/NonSemanticDebugPrintf.h @@ -0,0 +1,50 @@ +// Copyright (c) 2020 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and/or associated documentation files (the +// "Materials"), to deal in the Materials without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Materials, and to +// permit persons to whom the Materials are 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 Materials. +// +// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS +// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS +// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT +// https://www.khronos.org/registry/ +// +// THE MATERIALS ARE 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 +// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +// + +#ifndef SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_ +#define SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + NonSemanticDebugPrintfRevision = 1, + NonSemanticDebugPrintfRevision_BitWidthPadding = 0x7fffffff +}; + +enum NonSemanticDebugPrintfInstructions { + NonSemanticDebugPrintfDebugPrintf = 1, + NonSemanticDebugPrintfInstructionsMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_ diff --git a/src/libraries/glslang/SPIRV/SPVRemapper.cpp b/src/libraries/glslang/SPIRV/SPVRemapper.cpp index fd0bb8950..56d7f431a 100644 --- a/src/libraries/glslang/SPIRV/SPVRemapper.cpp +++ b/src/libraries/glslang/SPIRV/SPVRemapper.cpp @@ -625,6 +625,9 @@ namespace spv { break; } + case spv::OperandVariableLiteralStrings: + return nextInst; + // Execution mode might have extra literal operands. Skip them. case spv::OperandExecutionMode: return nextInst; @@ -827,7 +830,15 @@ namespace spv { [&](spv::Id& id) { if (thisOpCode != spv::OpNop) { ++idCounter; - const std::uint32_t hashval = opCounter[thisOpCode] * thisOpCode * 50047 + idCounter + fnId * 117; + const std::uint32_t hashval = + // Explicitly cast operands to unsigned int to avoid integer + // promotion to signed int followed by integer overflow, + // which would result in undefined behavior. + static_cast(opCounter[thisOpCode]) + * thisOpCode + * 50047 + + idCounter + + static_cast(fnId) * 117; if (isOldIdUnmapped(id)) localId(id, nextUnusedId(hashval % softTypeIdLimit + firstMappedID)); diff --git a/src/libraries/glslang/SPIRV/SpvBuilder.cpp b/src/libraries/glslang/SPIRV/SpvBuilder.cpp index bd208952e..968033146 100644 --- a/src/libraries/glslang/SPIRV/SpvBuilder.cpp +++ b/src/libraries/glslang/SPIRV/SpvBuilder.cpp @@ -1,6 +1,7 @@ // // Copyright (C) 2014-2015 LunarG, Inc. // Copyright (C) 2015-2018 Google, Inc. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -496,7 +497,8 @@ Id Builder::makeFunctionType(Id returnType, const std::vector& paramTypes) return type->getResultId(); } -Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format) +Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, bool ms, unsigned sampled, + ImageFormat format) { assert(sampled == 1 || sampled == 2); @@ -601,16 +603,31 @@ Id Builder::makeSampledImageType(Id imageType) } #ifndef GLSLANG_WEB -Id Builder::makeAccelerationStructureNVType() +Id Builder::makeAccelerationStructureType() { Instruction *type; - if (groupedTypes[OpTypeAccelerationStructureNV].size() == 0) { - type = new Instruction(getUniqueId(), NoType, OpTypeAccelerationStructureNV); - groupedTypes[OpTypeAccelerationStructureNV].push_back(type); + if (groupedTypes[OpTypeAccelerationStructureKHR].size() == 0) { + type = new Instruction(getUniqueId(), NoType, OpTypeAccelerationStructureKHR); + groupedTypes[OpTypeAccelerationStructureKHR].push_back(type); constantsTypesGlobals.push_back(std::unique_ptr(type)); module.mapInstruction(type); } else { - type = groupedTypes[OpTypeAccelerationStructureNV].back(); + type = groupedTypes[OpTypeAccelerationStructureKHR].back(); + } + + return type->getResultId(); +} + +Id Builder::makeRayQueryType() +{ + Instruction *type; + if (groupedTypes[OpTypeRayQueryProvisionalKHR].size() == 0) { + type = new Instruction(getUniqueId(), NoType, OpTypeRayQueryProvisionalKHR); + groupedTypes[OpTypeRayQueryProvisionalKHR].push_back(type); + constantsTypesGlobals.push_back(std::unique_ptr(type)); + module.mapInstruction(type); + } else { + type = groupedTypes[OpTypeRayQueryProvisionalKHR].back(); } return type->getResultId(); @@ -1166,6 +1183,28 @@ void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, int val executionModes.push_back(std::unique_ptr(instr)); } +void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, const std::vector& literals) +{ + Instruction* instr = new Instruction(OpExecutionMode); + instr->addIdOperand(entryPoint->getId()); + instr->addImmediateOperand(mode); + for (auto literal : literals) + instr->addImmediateOperand(literal); + + executionModes.push_back(std::unique_ptr(instr)); +} + +void Builder::addExecutionModeId(Function* entryPoint, ExecutionMode mode, const std::vector& operandIds) +{ + Instruction* instr = new Instruction(OpExecutionModeId); + instr->addIdOperand(entryPoint->getId()); + instr->addImmediateOperand(mode); + for (auto operandId : operandIds) + instr->addIdOperand(operandId); + + executionModes.push_back(std::unique_ptr(instr)); +} + void Builder::addName(Id id, const char* string) { Instruction* name = new Instruction(OpName); @@ -1204,7 +1243,7 @@ void Builder::addDecoration(Id id, Decoration decoration, const char* s) if (decoration == spv::DecorationMax) return; - Instruction* dec = new Instruction(OpDecorateStringGOOGLE); + Instruction* dec = new Instruction(OpDecorateString); dec->addIdOperand(id); dec->addImmediateOperand(decoration); dec->addStringOperand(s); @@ -1212,6 +1251,34 @@ void Builder::addDecoration(Id id, Decoration decoration, const char* s) decorations.push_back(std::unique_ptr(dec)); } +void Builder::addDecoration(Id id, Decoration decoration, const std::vector& literals) +{ + if (decoration == spv::DecorationMax) + return; + + Instruction* dec = new Instruction(OpDecorate); + dec->addIdOperand(id); + dec->addImmediateOperand(decoration); + for (auto literal : literals) + dec->addImmediateOperand(literal); + + decorations.push_back(std::unique_ptr(dec)); +} + +void Builder::addDecoration(Id id, Decoration decoration, const std::vector& strings) +{ + if (decoration == spv::DecorationMax) + return; + + Instruction* dec = new Instruction(OpDecorateString); + dec->addIdOperand(id); + dec->addImmediateOperand(decoration); + for (auto string : strings) + dec->addStringOperand(string); + + decorations.push_back(std::unique_ptr(dec)); +} + void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration) { if (decoration == spv::DecorationMax) @@ -1225,6 +1292,21 @@ void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration) decorations.push_back(std::unique_ptr(dec)); } +void Builder::addDecorationId(Id id, Decoration decoration, const std::vector& operandIds) +{ + if(decoration == spv::DecorationMax) + return; + + Instruction* dec = new Instruction(OpDecorateId); + dec->addIdOperand(id); + dec->addImmediateOperand(decoration); + + for (auto operandId : operandIds) + dec->addIdOperand(operandId); + + decorations.push_back(std::unique_ptr(dec)); +} + void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, int num) { if (decoration == spv::DecorationMax) @@ -1254,6 +1336,36 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat decorations.push_back(std::unique_ptr(dec)); } +void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const std::vector& literals) +{ + if (decoration == spv::DecorationMax) + return; + + Instruction* dec = new Instruction(OpMemberDecorate); + dec->addIdOperand(id); + dec->addImmediateOperand(member); + dec->addImmediateOperand(decoration); + for (auto literal : literals) + dec->addImmediateOperand(literal); + + decorations.push_back(std::unique_ptr(dec)); +} + +void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const std::vector& strings) +{ + if (decoration == spv::DecorationMax) + return; + + Instruction* dec = new Instruction(OpMemberDecorateString); + dec->addIdOperand(id); + dec->addImmediateOperand(member); + dec->addImmediateOperand(decoration); + for (auto string : strings) + dec->addStringOperand(string); + + decorations.push_back(std::unique_ptr(dec)); +} + // Comments in header Function* Builder::makeEntryPoint(const char* entryPoint) { @@ -1270,7 +1382,8 @@ Function* Builder::makeEntryPoint(const char* entryPoint) // Comments in header Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name, - const std::vector& paramTypes, const std::vector>& decorations, Block **entry) + const std::vector& paramTypes, + const std::vector>& decorations, Block **entry) { // Make the function and initial instructions in it Id typeId = makeFunctionType(returnType, paramTypes); @@ -1279,9 +1392,12 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const // Set up the precisions setPrecision(function->getId(), precision); + function->setReturnPrecision(precision); for (unsigned p = 0; p < (unsigned)decorations.size(); ++p) { - for (int d = 0; d < (int)decorations[p].size(); ++d) + for (int d = 0; d < (int)decorations[p].size(); ++d) { addDecoration(firstParamId + p, decorations[p][d]); + function->addParamPrecision(p, decorations[p][d]); + } } // CFG @@ -1338,7 +1454,7 @@ void Builder::makeDiscard() } // Comments in header -Id Builder::createVariable(StorageClass storageClass, Id type, const char* name, Id initializer) +Id Builder::createVariable(Decoration precision, StorageClass storageClass, Id type, const char* name, Id initializer) { Id pointerType = makePointer(storageClass, type); Instruction* inst = new Instruction(getUniqueId(), pointerType, OpVariable); @@ -1360,6 +1476,7 @@ Id Builder::createVariable(StorageClass storageClass, Id type, const char* name, if (name) addName(inst->getResultId(), name); + setPrecision(inst->getResultId(), precision); return inst->getResultId(); } @@ -1373,7 +1490,8 @@ Id Builder::createUndefined(Id type) } // av/vis/nonprivate are unnecessary and illegal for some storage classes. -spv::MemoryAccessMask Builder::sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc) const +spv::MemoryAccessMask Builder::sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc) + const { switch (sc) { case spv::StorageClassUniform: @@ -1392,7 +1510,8 @@ spv::MemoryAccessMask Builder::sanitizeMemoryAccessForStorageClass(spv::MemoryAc } // Comments in header -void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment) +void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, + unsigned int alignment) { Instruction* store = new Instruction(OpStore); store->addIdOperand(lValue); @@ -1414,7 +1533,8 @@ void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAcce } // Comments in header -Id Builder::createLoad(Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment) +Id Builder::createLoad(Id lValue, spv::Decoration precision, spv::MemoryAccessMask memoryAccess, + spv::Scope scope, unsigned int alignment) { Instruction* load = new Instruction(getUniqueId(), getDerefTypeId(lValue), OpLoad); load->addIdOperand(lValue); @@ -1432,6 +1552,7 @@ Id Builder::createLoad(Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope } buildPoint->addInstruction(std::unique_ptr(load)); + setPrecision(load->getResultId(), precision); return load->getResultId(); } @@ -1495,7 +1616,8 @@ Id Builder::createCompositeExtract(Id composite, Id typeId, unsigned index) // Generate code for spec constants if in spec constant operation // generation mode. if (generatingOpCodeForSpecConst) { - return createSpecConstantOp(OpCompositeExtract, typeId, std::vector(1, composite), std::vector(1, index)); + return createSpecConstantOp(OpCompositeExtract, typeId, std::vector(1, composite), + std::vector(1, index)); } Instruction* extract = new Instruction(getUniqueId(), typeId, OpCompositeExtract); extract->addIdOperand(composite); @@ -1697,7 +1819,8 @@ Id Builder::createOp(Op opCode, Id typeId, const std::vector& opera return op->getResultId(); } -Id Builder::createSpecConstantOp(Op opCode, Id typeId, const std::vector& operands, const std::vector& literals) +Id Builder::createSpecConstantOp(Op opCode, Id typeId, const std::vector& operands, + const std::vector& literals) { Instruction* op = new Instruction(getUniqueId(), typeId, OpSpecConstantOp); op->addImmediateOperand((unsigned) opCode); @@ -2144,7 +2267,7 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b Op op; switch (getMostBasicTypeClass(valueType)) { case OpTypeFloat: - op = equal ? OpFOrdEqual : OpFOrdNotEqual; + op = equal ? OpFOrdEqual : OpFUnordNotEqual; break; case OpTypeInt: default: @@ -2187,7 +2310,8 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b if (constituent == 0) resultId = subResultId; else - resultId = setPrecision(createBinOp(equal ? OpLogicalAnd : OpLogicalOr, boolType, resultId, subResultId), precision); + resultId = setPrecision(createBinOp(equal ? OpLogicalAnd : OpLogicalOr, boolType, resultId, subResultId), + precision); } return resultId; @@ -2196,7 +2320,8 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b // OpCompositeConstruct Id Builder::createCompositeConstruct(Id typeId, const std::vector& constituents) { - assert(isAggregateType(typeId) || (getNumTypeConstituents(typeId) > 1 && getNumTypeConstituents(typeId) == (int)constituents.size())); + assert(isAggregateType(typeId) || (getNumTypeConstituents(typeId) > 1 && + getNumTypeConstituents(typeId) == (int)constituents.size())); if (generatingOpCodeForSpecConst) { // Sometime, even in spec-constant-op mode, the constant composite to be @@ -2609,7 +2734,8 @@ void Builder::clearAccessChain() } // Comments in header -void Builder::accessChainPushSwizzle(std::vector& swizzle, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment) +void Builder::accessChainPushSwizzle(std::vector& swizzle, Id preSwizzleBaseType, + AccessChain::CoherentFlags coherentFlags, unsigned int alignment) { accessChain.coherentFlags |= coherentFlags; accessChain.alignment |= alignment; @@ -2649,7 +2775,7 @@ void Builder::accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess, sp // If swizzle still exists, it is out-of-order or not full, we must load the target vector, // extract and insert elements to perform writeMask and/or swizzle. if (accessChain.swizzle.size() > 0) { - Id tempBaseId = createLoad(base); + Id tempBaseId = createLoad(base, spv::NoPrecision); source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle); } @@ -2663,7 +2789,8 @@ void Builder::accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess, sp } // Comments in header -Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resultType, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment) +Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resultType, + spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment) { Id id; @@ -2687,17 +2814,19 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu if (constant) { id = createCompositeExtract(accessChain.base, swizzleBase, indexes); + setPrecision(id, precision); } else { Id lValue = NoResult; - if (spvVersion >= Spv_1_4) { + if (spvVersion >= Spv_1_4 && isValidInitializer(accessChain.base)) { // make a new function variable for this r-value, using an initializer, // and mark it as NonWritable so that downstream it can be detected as a lookup // table - lValue = createVariable(StorageClassFunction, getTypeId(accessChain.base), "indexable", - accessChain.base); + lValue = createVariable(NoPrecision, StorageClassFunction, getTypeId(accessChain.base), + "indexable", accessChain.base); addDecoration(lValue, DecorationNonWritable); } else { - lValue = createVariable(StorageClassFunction, getTypeId(accessChain.base), "indexable"); + lValue = createVariable(NoPrecision, StorageClassFunction, getTypeId(accessChain.base), + "indexable"); // store into it createStore(accessChain.base, lValue); } @@ -2706,9 +2835,8 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu accessChain.isRValue = false; // load through the access chain - id = createLoad(collapseAccessChain()); + id = createLoad(collapseAccessChain(), precision); } - setPrecision(id, precision); } else id = accessChain.base; // no precision, it was set when this was defined } else { @@ -2721,8 +2849,13 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu } // load through the access chain - id = createLoad(collapseAccessChain(), memoryAccess, scope, alignment); - setPrecision(id, precision); + id = collapseAccessChain(); + // Apply nonuniform both to the access chain and the loaded value. + // Buffer accesses need the access chain decorated, and this is where + // loaded image types get decorated. TODO: This should maybe move to + // createImageTextureFunctionCall. + addDecoration(id, nonUniform); + id = createLoad(id, precision, memoryAccess, scope, alignment); addDecoration(id, nonUniform); } @@ -3075,7 +3208,8 @@ void Builder::dumpSourceInstructions(std::vector& out) const dumpSourceInstructions(iItr->first, *iItr->second, out); } -void Builder::dumpInstructions(std::vector& out, const std::vector >& instructions) const +void Builder::dumpInstructions(std::vector& out, + const std::vector >& instructions) const { for (int i = 0; i < (int)instructions.size(); ++i) { instructions[i]->dump(out); diff --git a/src/libraries/glslang/SPIRV/SpvBuilder.h b/src/libraries/glslang/SPIRV/SpvBuilder.h index 31fee975f..077945e77 100644 --- a/src/libraries/glslang/SPIRV/SpvBuilder.h +++ b/src/libraries/glslang/SPIRV/SpvBuilder.h @@ -1,7 +1,8 @@ // // Copyright (C) 2014-2015 LunarG, Inc. -// Copyright (C) 2015-2018 Google, Inc. +// Copyright (C) 2015-2020 Google, Inc. // Copyright (C) 2017 ARM Limited. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -94,6 +95,7 @@ public: const char* file_c_str = str.c_str(); fileString->addStringOperand(file_c_str); strings.push_back(std::unique_ptr(fileString)); + module.mapInstruction(fileString); stringIds[file_c_str] = strId; return strId; } @@ -181,7 +183,9 @@ public: Id makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols); // accelerationStructureNV type - Id makeAccelerationStructureNVType(); + Id makeAccelerationStructureType(); + // rayQueryEXT type + Id makeRayQueryType(); // For querying about types. Id getTypeId(Id resultId) const { return module.getTypeId(resultId); } @@ -196,7 +200,8 @@ public: Id getContainedTypeId(Id typeId) const; Id getContainedTypeId(Id typeId, int) const; StorageClass getTypeStorageClass(Id typeId) const { return module.getStorageClass(typeId); } - ImageFormat getImageTypeFormat(Id typeId) const { return (ImageFormat)module.getInstruction(typeId)->getImmediateOperand(6); } + ImageFormat getImageTypeFormat(Id typeId) const + { return (ImageFormat)module.getInstruction(typeId)->getImmediateOperand(6); } bool isPointer(Id resultId) const { return isPointerType(getTypeId(resultId)); } bool isScalar(Id resultId) const { return isScalarType(getTypeId(resultId)); } @@ -206,12 +211,17 @@ public: bool isAggregate(Id resultId) const { return isAggregateType(getTypeId(resultId)); } bool isSampledImage(Id resultId) const { return isSampledImageType(getTypeId(resultId)); } - bool isBoolType(Id typeId) { return groupedTypes[OpTypeBool].size() > 0 && typeId == groupedTypes[OpTypeBool].back()->getResultId(); } - bool isIntType(Id typeId) const { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) != 0; } - bool isUintType(Id typeId) const { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) == 0; } + bool isBoolType(Id typeId) + { return groupedTypes[OpTypeBool].size() > 0 && typeId == groupedTypes[OpTypeBool].back()->getResultId(); } + bool isIntType(Id typeId) const + { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) != 0; } + bool isUintType(Id typeId) const + { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) == 0; } bool isFloatType(Id typeId) const { return getTypeClass(typeId) == OpTypeFloat; } bool isPointerType(Id typeId) const { return getTypeClass(typeId) == OpTypePointer; } - bool isScalarType(Id typeId) const { return getTypeClass(typeId) == OpTypeFloat || getTypeClass(typeId) == OpTypeInt || getTypeClass(typeId) == OpTypeBool; } + bool isScalarType(Id typeId) const + { return getTypeClass(typeId) == OpTypeFloat || getTypeClass(typeId) == OpTypeInt || + getTypeClass(typeId) == OpTypeBool; } bool isVectorType(Id typeId) const { return getTypeClass(typeId) == OpTypeVector; } bool isMatrixType(Id typeId) const { return getTypeClass(typeId) == OpTypeMatrix; } bool isStructType(Id typeId) const { return getTypeClass(typeId) == OpTypeStruct; } @@ -221,7 +231,8 @@ public: #else bool isCooperativeMatrixType(Id typeId)const { return getTypeClass(typeId) == OpTypeCooperativeMatrixNV; } #endif - bool isAggregateType(Id typeId) const { return isArrayType(typeId) || isStructType(typeId) || isCooperativeMatrixType(typeId); } + bool isAggregateType(Id typeId) const + { return isArrayType(typeId) || isStructType(typeId) || isCooperativeMatrixType(typeId); } bool isImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeImage; } bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampler; } bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampledImage; } @@ -233,9 +244,17 @@ public: bool isConstant(Id resultId) const { return isConstantOpCode(getOpCode(resultId)); } bool isConstantScalar(Id resultId) const { return getOpCode(resultId) == OpConstant; } bool isSpecConstant(Id resultId) const { return isSpecConstantOpCode(getOpCode(resultId)); } - unsigned int getConstantScalar(Id resultId) const { return module.getInstruction(resultId)->getImmediateOperand(0); } + unsigned int getConstantScalar(Id resultId) const + { return module.getInstruction(resultId)->getImmediateOperand(0); } StorageClass getStorageClass(Id resultId) const { return getTypeStorageClass(getTypeId(resultId)); } + bool isVariableOpCode(Op opcode) const { return opcode == OpVariable; } + bool isVariable(Id resultId) const { return isVariableOpCode(getOpCode(resultId)); } + bool isGlobalStorage(Id resultId) const { return getStorageClass(resultId) != StorageClassFunction; } + bool isGlobalVariable(Id resultId) const { return isVariable(resultId) && isGlobalStorage(resultId); } + // See if a resultId is valid for use as an initializer. + bool isValidInitializer(Id resultId) const { return isConstant(resultId) || isGlobalVariable(resultId); } + int getScalarTypeWidth(Id typeId) const { Id scalarTypeId = getScalarTypeId(typeId); @@ -275,14 +294,22 @@ public: // For making new constants (will return old constant if the requested one was already made). Id makeBoolConstant(bool b, bool specConstant = false); - Id makeInt8Constant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(8), (unsigned)i, specConstant); } - Id makeUint8Constant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(8), u, specConstant); } - Id makeInt16Constant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(16), (unsigned)i, specConstant); } - Id makeUint16Constant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(16), u, specConstant); } - Id makeIntConstant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(32), (unsigned)i, specConstant); } - Id makeUintConstant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(32), u, specConstant); } - Id makeInt64Constant(long long i, bool specConstant = false) { return makeInt64Constant(makeIntType(64), (unsigned long long)i, specConstant); } - Id makeUint64Constant(unsigned long long u, bool specConstant = false) { return makeInt64Constant(makeUintType(64), u, specConstant); } + Id makeInt8Constant(int i, bool specConstant = false) + { return makeIntConstant(makeIntType(8), (unsigned)i, specConstant); } + Id makeUint8Constant(unsigned u, bool specConstant = false) + { return makeIntConstant(makeUintType(8), u, specConstant); } + Id makeInt16Constant(int i, bool specConstant = false) + { return makeIntConstant(makeIntType(16), (unsigned)i, specConstant); } + Id makeUint16Constant(unsigned u, bool specConstant = false) + { return makeIntConstant(makeUintType(16), u, specConstant); } + Id makeIntConstant(int i, bool specConstant = false) + { return makeIntConstant(makeIntType(32), (unsigned)i, specConstant); } + Id makeUintConstant(unsigned u, bool specConstant = false) + { return makeIntConstant(makeUintType(32), u, specConstant); } + Id makeInt64Constant(long long i, bool specConstant = false) + { return makeInt64Constant(makeIntType(64), (unsigned long long)i, specConstant); } + Id makeUint64Constant(unsigned long long u, bool specConstant = false) + { return makeInt64Constant(makeUintType(64), u, specConstant); } Id makeFloatConstant(float f, bool specConstant = false); Id makeDoubleConstant(double d, bool specConstant = false); Id makeFloat16Constant(float f16, bool specConstant = false); @@ -294,13 +321,20 @@ public: // Methods for adding information outside the CFG. Instruction* addEntryPoint(ExecutionModel, Function*, const char* name); void addExecutionMode(Function*, ExecutionMode mode, int value1 = -1, int value2 = -1, int value3 = -1); + void addExecutionMode(Function*, ExecutionMode mode, const std::vector& literals); + void addExecutionModeId(Function*, ExecutionMode mode, const std::vector& operandIds); void addName(Id, const char* name); void addMemberName(Id, int member, const char* name); void addDecoration(Id, Decoration, int num = -1); void addDecoration(Id, Decoration, const char*); + void addDecoration(Id, Decoration, const std::vector& literals); + void addDecoration(Id, Decoration, const std::vector& strings); void addDecorationId(Id id, Decoration, Id idDecoration); + void addDecorationId(Id id, Decoration, const std::vector& operandIds); void addMemberDecoration(Id, unsigned int member, Decoration, int num = -1); void addMemberDecoration(Id, unsigned int member, Decoration, const char*); + void addMemberDecoration(Id, unsigned int member, Decoration, const std::vector& literals); + void addMemberDecoration(Id, unsigned int member, Decoration, const std::vector& strings); // At the end of what block do the next create*() instructions go? void setBuildPoint(Block* bp) { buildPoint = bp; } @@ -313,8 +347,8 @@ public: // Make a shader-style function, and create its entry block if entry is non-zero. // Return the function, pass back the entry. // The returned pointer is only valid for the lifetime of this builder. - Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name, const std::vector& paramTypes, - const std::vector>& precisions, Block **entry = 0); + Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name, + const std::vector& paramTypes, const std::vector>& precisions, Block **entry = 0); // Create a return. An 'implicit' return is one not appearing in the source // code. In the case of an implicit return, no post-return block is inserted. @@ -327,16 +361,20 @@ public: void makeDiscard(); // Create a global or function local or IO variable. - Id createVariable(StorageClass, Id type, const char* name = 0, Id initializer = NoResult); + Id createVariable(Decoration precision, StorageClass, Id type, const char* name = nullptr, + Id initializer = NoResult); // Create an intermediate with an undefined value. Id createUndefined(Id type); // Store into an Id and return the l-value - void createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0); + void createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, + spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0); // Load from an Id and return it - Id createLoad(Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0); + Id createLoad(Id lValue, spv::Decoration precision, + spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, + spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0); // Create an OpAccessChain instruction Id createAccessChain(StorageClass, Id base, const std::vector& offsets); @@ -495,7 +533,7 @@ public: // recursion stack can hold the memory for it. // void makeSwitch(Id condition, unsigned int control, int numSegments, const std::vector& caseValues, - const std::vector& valueToSegment, int defaultSegment, std::vector& segmentBB); // return argument + const std::vector& valueToSegment, int defaultSegment, std::vector& segmentBB); // Add a branch to the innermost switch's merge block. void addSwitchBreak(); @@ -512,7 +550,7 @@ public: Block &head, &body, &merge, &continue_target; private: LoopBlocks(); - LoopBlocks& operator=(const LoopBlocks&); + LoopBlocks& operator=(const LoopBlocks&) = delete; }; // Start a new loop and prepare the builder to generate code for it. Until @@ -569,10 +607,13 @@ public: std::vector indexChain; Id instr; // cache the instruction that generates this access chain std::vector swizzle; // each std::vector element selects the next GLSL component number - Id component; // a dynamic component index, can coexist with a swizzle, done after the swizzle, NoResult if not present - Id preSwizzleBaseType; // dereferenced type, before swizzle or component is applied; NoType unless a swizzle or component is present + Id component; // a dynamic component index, can coexist with a swizzle, + // done after the swizzle, NoResult if not present + Id preSwizzleBaseType; // dereferenced type, before swizzle or component is applied; + // NoType unless a swizzle or component is present bool isRValue; // true if 'base' is an r-value, otherwise, base is an l-value - unsigned int alignment; // bitwise OR of alignment values passed in. Accumulates worst alignment. Only tracks base and (optional) component selection alignment. + unsigned int alignment; // bitwise OR of alignment values passed in. Accumulates worst alignment. + // Only tracks base and (optional) component selection alignment. // Accumulate whether anything in the chain of structures has coherent decorations. struct CoherentFlags { @@ -583,12 +624,17 @@ public: CoherentFlags operator |=(const CoherentFlags &other) { return *this; } #else bool isVolatile() const { return volatil; } + bool anyCoherent() const { + return coherent || devicecoherent || queuefamilycoherent || workgroupcoherent || + subgroupcoherent || shadercallcoherent; + } unsigned coherent : 1; unsigned devicecoherent : 1; unsigned queuefamilycoherent : 1; unsigned workgroupcoherent : 1; unsigned subgroupcoherent : 1; + unsigned shadercallcoherent : 1; unsigned nonprivate : 1; unsigned volatil : 1; unsigned isImage : 1; @@ -599,6 +645,7 @@ public: queuefamilycoherent = 0; workgroupcoherent = 0; subgroupcoherent = 0; + shadercallcoherent = 0; nonprivate = 0; volatil = 0; isImage = 0; @@ -610,6 +657,7 @@ public: queuefamilycoherent |= other.queuefamilycoherent; workgroupcoherent |= other.workgroupcoherent; subgroupcoherent |= other.subgroupcoherent; + shadercallcoherent |= other.shadercallcoherent; nonprivate |= other.nonprivate; volatil |= other.volatil; isImage |= other.isImage; @@ -655,11 +703,13 @@ public: } // push new swizzle onto the end of any existing swizzle, merging into a single swizzle - void accessChainPushSwizzle(std::vector& swizzle, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment); + void accessChainPushSwizzle(std::vector& swizzle, Id preSwizzleBaseType, + AccessChain::CoherentFlags coherentFlags, unsigned int alignment); // push a dynamic component selection onto the access chain, only applicable with a // non-trivial swizzle or no swizzle - void accessChainPushComponent(Id component, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment) + void accessChainPushComponent(Id component, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, + unsigned int alignment) { if (accessChain.swizzle.size() != 1) { accessChain.component = component; @@ -671,10 +721,18 @@ public: } // use accessChain and swizzle to store value - void accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0); + void accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, + spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0); // use accessChain and swizzle to load an r-value - Id accessChainLoad(Decoration precision, Decoration nonUniform, Id ResultType, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0); + Id accessChainLoad(Decoration precision, Decoration nonUniform, Id ResultType, + spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, + unsigned int alignment = 0); + + // Return whether or not the access chain can be represented in SPIR-V + // as an l-value. + // E.g., a[3].yx cannot be, while a[3].y and a[3].y[x] can be. + bool isSpvLvalue() const { return accessChain.swizzle.size() <= 1; } // get the direct pointer for an l-value Id accessChainGetLValue(); @@ -703,7 +761,8 @@ public: void createBranch(Block* block); void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock); - void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control, const std::vector& operands); + void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control, + const std::vector& operands); // Sets to generate opcode for specialization constants. void setToSpecConstCodeGenMode() { generatingOpCodeForSpecConst = true; } @@ -729,7 +788,8 @@ public: void dumpSourceInstructions(const spv::Id fileId, const std::string& text, std::vector&) const; void dumpInstructions(std::vector&, const std::vector >&) const; void dumpModuleProcesses(std::vector&) const; - spv::MemoryAccessMask sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc) const; + spv::MemoryAccessMask sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc) + const; unsigned int spvVersion; // the version of SPIR-V to emit in the header SourceLanguage source; @@ -764,10 +824,14 @@ public: std::vector > externals; std::vector > functions; - // not output, internally used for quick & dirty canonical (unique) creation - std::unordered_map> groupedConstants; // map type opcodes to constant inst. - std::unordered_map> groupedStructConstants; // map struct-id to constant instructions - std::unordered_map> groupedTypes; // map type opcodes to type instructions + // not output, internally used for quick & dirty canonical (unique) creation + + // map type opcodes to constant inst. + std::unordered_map> groupedConstants; + // map struct-id to constant instructions + std::unordered_map> groupedStructConstants; + // map type opcodes to type instructions + std::unordered_map> groupedTypes; // stack of switches std::stack switchMerges; diff --git a/src/libraries/glslang/SPIRV/SpvTools.cpp b/src/libraries/glslang/SPIRV/SpvTools.cpp index 7c3b03919..112ac33c5 100644 --- a/src/libraries/glslang/SPIRV/SpvTools.cpp +++ b/src/libraries/glslang/SPIRV/SpvTools.cpp @@ -1,6 +1,6 @@ // // Copyright (C) 2014-2016 LunarG, Inc. -// Copyright (C) 2018 Google, Inc. +// Copyright (C) 2018-2020 Google, Inc. // // All rights reserved. // @@ -67,6 +67,8 @@ spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLog logger->missingFunctionality("Target version for SPIRV-Tools validator"); return spv_target_env::SPV_ENV_VULKAN_1_1; } + case glslang::EShTargetVulkan_1_2: + return spv_target_env::SPV_ENV_VULKAN_1_2; default: break; } @@ -78,6 +80,39 @@ spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLog return spv_target_env::SPV_ENV_UNIVERSAL_1_0; } +// Callback passed to spvtools::Optimizer::SetMessageConsumer +void OptimizerMesssageConsumer(spv_message_level_t level, const char *source, + const spv_position_t &position, const char *message) +{ + auto &out = std::cerr; + switch (level) + { + case SPV_MSG_FATAL: + case SPV_MSG_INTERNAL_ERROR: + case SPV_MSG_ERROR: + out << "error: "; + break; + case SPV_MSG_WARNING: + out << "warning: "; + break; + case SPV_MSG_INFO: + case SPV_MSG_DEBUG: + out << "info: "; + break; + default: + break; + } + if (source) + { + out << source << ":"; + } + out << position.line << ":" << position.column << ":" << position.index << ":"; + if (message) + { + out << " " << message; + } + out << std::endl; +} // Use the SPIRV-Tools disassembler to print SPIR-V. void SpirvToolsDisassemble(std::ostream& out, const std::vector& spirv) @@ -126,45 +161,14 @@ void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector< spvContextDestroy(context); } -// Apply the SPIRV-Tools optimizer to generated SPIR-V, for the purpose of -// legalizing HLSL SPIR-V. -void SpirvToolsLegalize(const glslang::TIntermediate&, std::vector& spirv, - spv::SpvBuildLogger*, const SpvOptions* options) +// Apply the SPIRV-Tools optimizer to generated SPIR-V. HLSL SPIR-V is legalized in the process. +void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector& spirv, + spv::SpvBuildLogger* logger, const SpvOptions* options) { - spv_target_env target_env = SPV_ENV_UNIVERSAL_1_2; + spv_target_env target_env = MapToSpirvToolsEnv(intermediate.getSpv(), logger); spvtools::Optimizer optimizer(target_env); - optimizer.SetMessageConsumer( - [](spv_message_level_t level, const char *source, const spv_position_t &position, const char *message) { - auto &out = std::cerr; - switch (level) - { - case SPV_MSG_FATAL: - case SPV_MSG_INTERNAL_ERROR: - case SPV_MSG_ERROR: - out << "error: "; - break; - case SPV_MSG_WARNING: - out << "warning: "; - break; - case SPV_MSG_INFO: - case SPV_MSG_DEBUG: - out << "info: "; - break; - default: - break; - } - if (source) - { - out << source << ":"; - } - out << position.line << ":" << position.column << ":" << position.index << ":"; - if (message) - { - out << " " << message; - } - out << std::endl; - }); + optimizer.SetMessageConsumer(OptimizerMesssageConsumer); // If debug (specifically source line info) is being generated, propagate // line information into all SPIR-V instructions. This avoids loss of @@ -173,6 +177,9 @@ void SpirvToolsLegalize(const glslang::TIntermediate&, std::vector if (options->generateDebugInfo) { optimizer.RegisterPass(spvtools::CreatePropagateLineInfoPass()); } + else if (options->stripDebugInfo) { + optimizer.RegisterPass(spvtools::CreateStripDebugInfoPass()); + } optimizer.RegisterPass(spvtools::CreateWrapOpKillPass()); optimizer.RegisterPass(spvtools::CreateDeadBranchElimPass()); optimizer.RegisterPass(spvtools::CreateMergeReturnPass()); @@ -205,7 +212,27 @@ void SpirvToolsLegalize(const glslang::TIntermediate&, std::vector } spvtools::OptimizerOptions spvOptOptions; - spvOptOptions.set_run_validator(false); // The validator may run as a seperate step later on + optimizer.SetTargetEnv(MapToSpirvToolsEnv(intermediate.getSpv(), logger)); + spvOptOptions.set_run_validator(false); // The validator may run as a separate step later on + optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions); +} + +// Apply the SPIRV-Tools optimizer to strip debug info from SPIR-V. This is implicitly done by +// SpirvToolsTransform if spvOptions->stripDebugInfo is set, but can be called separately if +// optimization is disabled. +void SpirvToolsStripDebugInfo(const glslang::TIntermediate& intermediate, + std::vector& spirv, spv::SpvBuildLogger* logger) +{ + spv_target_env target_env = MapToSpirvToolsEnv(intermediate.getSpv(), logger); + + spvtools::Optimizer optimizer(target_env); + optimizer.SetMessageConsumer(OptimizerMesssageConsumer); + + optimizer.RegisterPass(spvtools::CreateStripDebugInfoPass()); + + spvtools::OptimizerOptions spvOptOptions; + optimizer.SetTargetEnv(MapToSpirvToolsEnv(intermediate.getSpv(), logger)); + spvOptOptions.set_run_validator(false); // The validator may run as a separate step later on optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions); } diff --git a/src/libraries/glslang/SPIRV/SpvTools.h b/src/libraries/glslang/SPIRV/SpvTools.h index 7422d0126..49449cc5a 100644 --- a/src/libraries/glslang/SPIRV/SpvTools.h +++ b/src/libraries/glslang/SPIRV/SpvTools.h @@ -52,9 +52,10 @@ namespace glslang { struct SpvOptions { - SpvOptions() : generateDebugInfo(false), disableOptimizer(true), + SpvOptions() : generateDebugInfo(false), stripDebugInfo(false), disableOptimizer(true), optimizeSize(false), disassemble(false), validate(false) { } bool generateDebugInfo; + bool stripDebugInfo; bool disableOptimizer; bool optimizeSize; bool disassemble; @@ -70,10 +71,15 @@ void SpirvToolsDisassemble(std::ostream& out, const std::vector& s void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector& spirv, spv::SpvBuildLogger*, bool prelegalization); -// Apply the SPIRV-Tools optimizer to generated SPIR-V, for the purpose of -// legalizing HLSL SPIR-V. -void SpirvToolsLegalize(const glslang::TIntermediate& intermediate, std::vector& spirv, - spv::SpvBuildLogger*, const SpvOptions*); +// Apply the SPIRV-Tools optimizer to generated SPIR-V. HLSL SPIR-V is legalized in the process. +void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector& spirv, + spv::SpvBuildLogger*, const SpvOptions*); + +// Apply the SPIRV-Tools optimizer to strip debug info from SPIR-V. This is implicitly done by +// SpirvToolsTransform if spvOptions->stripDebugInfo is set, but can be called separately if +// optimization is disabled. +void SpirvToolsStripDebugInfo(const glslang::TIntermediate& intermediate, + std::vector& spirv, spv::SpvBuildLogger*); #endif diff --git a/src/libraries/glslang/SPIRV/disassemble.cpp b/src/libraries/glslang/SPIRV/disassemble.cpp index 930e79949..73c988c5b 100644 --- a/src/libraries/glslang/SPIRV/disassemble.cpp +++ b/src/libraries/glslang/SPIRV/disassemble.cpp @@ -46,7 +46,6 @@ #include "disassemble.h" #include "doc.h" -#include "SpvTools.h" namespace spv { extern "C" { @@ -75,6 +74,7 @@ enum ExtInstSet { GLSLextAMDInst, GLSLextNVInst, OpenCLExtInst, + NonSemanticDebugPrintfExtInst, }; // Container class for a single instance of a SPIR-V stream, with methods for disassembly. @@ -480,8 +480,12 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, if (opCode == OpExtInst) { ExtInstSet extInstSet = GLSL450Inst; const char* name = idDescriptor[stream[word - 2]].c_str(); - if (0 == memcmp("OpenCL", name, 6)) { + if (strcmp("OpenCL.std", name) == 0) { extInstSet = OpenCLExtInst; + } else if (strcmp("OpenCL.DebugInfo.100", name) == 0) { + extInstSet = OpenCLExtInst; + } else if (strcmp("NonSemantic.DebugPrintf", name) == 0) { + extInstSet = NonSemanticDebugPrintfExtInst; } else if (strcmp(spv::E_SPV_AMD_shader_ballot, name) == 0 || strcmp(spv::E_SPV_AMD_shader_trinary_minmax, name) == 0 || strcmp(spv::E_SPV_AMD_shader_explicit_vertex_parameter, name) == 0 || @@ -505,6 +509,8 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, } else if (extInstSet == GLSLextNVInst) { out << "(" << GLSLextNVGetDebugNames(name, entrypoint) << ")"; + } else if (extInstSet == NonSemanticDebugPrintfExtInst) { + out << "(DebugPrintf)"; } } break; @@ -512,6 +518,10 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, case OperandLiteralString: numOperands -= disassembleString(); break; + case OperandVariableLiteralStrings: + while (numOperands > 0) + numOperands -= disassembleString(); + return; case OperandMemoryAccess: outputMask(OperandMemoryAccess, stream[word++]); --numOperands; diff --git a/src/libraries/glslang/SPIRV/doc.cpp b/src/libraries/glslang/SPIRV/doc.cpp index bee5c7972..1d052f8c2 100644 --- a/src/libraries/glslang/SPIRV/doc.cpp +++ b/src/libraries/glslang/SPIRV/doc.cpp @@ -1,5 +1,6 @@ // // Copyright (C) 2014-2015 LunarG, Inc. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -99,12 +100,12 @@ const char* ExecutionModelString(int model) default: return "Bad"; - case ExecutionModelRayGenerationNV: return "RayGenerationNV"; - case ExecutionModelIntersectionNV: return "IntersectionNV"; - case ExecutionModelAnyHitNV: return "AnyHitNV"; - case ExecutionModelClosestHitNV: return "ClosestHitNV"; - case ExecutionModelMissNV: return "MissNV"; - case ExecutionModelCallableNV: return "CallableNV"; + case ExecutionModelRayGenerationKHR: return "RayGenerationKHR"; + case ExecutionModelIntersectionKHR: return "IntersectionKHR"; + case ExecutionModelAnyHitKHR: return "AnyHitKHR"; + case ExecutionModelClosestHitKHR: return "ClosestHitKHR"; + case ExecutionModelMissKHR: return "MissKHR"; + case ExecutionModelCallableKHR: return "CallableKHR"; } } @@ -133,7 +134,7 @@ const char* MemoryString(int mem) } } -const int ExecutionModeCeiling = 33; +const int ExecutionModeCeiling = 40; const char* ExecutionModeString(int mode) { @@ -172,7 +173,21 @@ const char* ExecutionModeString(int mode) case 31: return "ContractionOff"; case 32: return "Bad"; - case 4446: return "PostDepthCoverage"; + case ExecutionModeInitializer: return "Initializer"; + case ExecutionModeFinalizer: return "Finalizer"; + case ExecutionModeSubgroupSize: return "SubgroupSize"; + case ExecutionModeSubgroupsPerWorkgroup: return "SubgroupsPerWorkgroup"; + case ExecutionModeSubgroupsPerWorkgroupId: return "SubgroupsPerWorkgroupId"; + case ExecutionModeLocalSizeId: return "LocalSizeId"; + case ExecutionModeLocalSizeHintId: return "LocalSizeHintId"; + + case ExecutionModePostDepthCoverage: return "PostDepthCoverage"; + case ExecutionModeDenormPreserve: return "DenormPreserve"; + case ExecutionModeDenormFlushToZero: return "DenormFlushToZero"; + case ExecutionModeSignedZeroInfNanPreserve: return "SignedZeroInfNanPreserve"; + case ExecutionModeRoundingModeRTE: return "RoundingModeRTE"; + case ExecutionModeRoundingModeRTZ: return "RoundingModeRTZ"; + case ExecutionModeStencilRefReplacingEXT: return "StencilRefReplacingEXT"; case ExecutionModeOutputLinesNV: return "OutputLinesNV"; case ExecutionModeOutputPrimitivesNV: return "OutputPrimitivesNV"; @@ -187,6 +202,11 @@ const char* ExecutionModeString(int mode) case ExecutionModeShadingRateInterlockOrderedEXT: return "ShadingRateInterlockOrderedEXT"; case ExecutionModeShadingRateInterlockUnorderedEXT: return "ShadingRateInterlockUnorderedEXT"; + case ExecutionModeMaxWorkgroupSizeINTEL: return "MaxWorkgroupSizeINTEL"; + case ExecutionModeMaxWorkDimINTEL: return "MaxWorkDimINTEL"; + case ExecutionModeNoGlobalOffsetINTEL: return "NoGlobalOffsetINTEL"; + case ExecutionModeNumSIMDWorkitemsINTEL: return "NumSIMDWorkitemsINTEL"; + case ExecutionModeCeiling: default: return "Bad"; } @@ -209,12 +229,12 @@ const char* StorageClassString(int StorageClass) case 11: return "Image"; case 12: return "StorageBuffer"; - case StorageClassRayPayloadNV: return "RayPayloadNV"; - case StorageClassHitAttributeNV: return "HitAttributeNV"; - case StorageClassIncomingRayPayloadNV: return "IncomingRayPayloadNV"; - case StorageClassShaderRecordBufferNV: return "ShaderRecordBufferNV"; - case StorageClassCallableDataNV: return "CallableDataNV"; - case StorageClassIncomingCallableDataNV: return "IncomingCallableDataNV"; + case StorageClassRayPayloadKHR: return "RayPayloadKHR"; + case StorageClassHitAttributeKHR: return "HitAttributeKHR"; + case StorageClassIncomingRayPayloadKHR: return "IncomingRayPayloadKHR"; + case StorageClassShaderRecordBufferKHR: return "ShaderRecordBufferKHR"; + case StorageClassCallableDataKHR: return "CallableDataKHR"; + case StorageClassIncomingCallableDataKHR: return "IncomingCallableDataKHR"; case StorageClassPhysicalStorageBufferEXT: return "PhysicalStorageBufferEXT"; @@ -361,32 +381,33 @@ const char* BuiltInString(int builtIn) case 4996: return "BaryCoordSmoothCentroidAMD"; case 4997: return "BaryCoordSmoothSampleAMD"; case 4998: return "BaryCoordPullModelAMD"; - case BuiltInLaunchIdNV: return "LaunchIdNV"; - case BuiltInLaunchSizeNV: return "LaunchSizeNV"; - case BuiltInWorldRayOriginNV: return "WorldRayOriginNV"; - case BuiltInWorldRayDirectionNV: return "WorldRayDirectionNV"; - case BuiltInObjectRayOriginNV: return "ObjectRayOriginNV"; - case BuiltInObjectRayDirectionNV: return "ObjectRayDirectionNV"; - case BuiltInRayTminNV: return "RayTminNV"; - case BuiltInRayTmaxNV: return "RayTmaxNV"; - case BuiltInInstanceCustomIndexNV: return "InstanceCustomIndexNV"; - case BuiltInObjectToWorldNV: return "ObjectToWorldNV"; - case BuiltInWorldToObjectNV: return "WorldToObjectNV"; - case BuiltInHitTNV: return "HitTNV"; - case BuiltInHitKindNV: return "HitKindNV"; - case BuiltInIncomingRayFlagsNV: return "IncomingRayFlagsNV"; - case BuiltInViewportMaskNV: return "ViewportMaskNV"; - case BuiltInSecondaryPositionNV: return "SecondaryPositionNV"; - case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV"; - case BuiltInPositionPerViewNV: return "PositionPerViewNV"; - case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV"; + case BuiltInLaunchIdKHR: return "LaunchIdKHR"; + case BuiltInLaunchSizeKHR: return "LaunchSizeKHR"; + case BuiltInWorldRayOriginKHR: return "WorldRayOriginKHR"; + case BuiltInWorldRayDirectionKHR: return "WorldRayDirectionKHR"; + case BuiltInObjectRayOriginKHR: return "ObjectRayOriginKHR"; + case BuiltInObjectRayDirectionKHR: return "ObjectRayDirectionKHR"; + case BuiltInRayTminKHR: return "RayTminKHR"; + case BuiltInRayTmaxKHR: return "RayTmaxKHR"; + case BuiltInInstanceCustomIndexKHR: return "InstanceCustomIndexKHR"; + case BuiltInRayGeometryIndexKHR: return "RayGeometryIndexKHR"; + case BuiltInObjectToWorldKHR: return "ObjectToWorldKHR"; + case BuiltInWorldToObjectKHR: return "WorldToObjectKHR"; + case BuiltInHitTKHR: return "HitTKHR"; + case BuiltInHitKindKHR: return "HitKindKHR"; + case BuiltInIncomingRayFlagsKHR: return "IncomingRayFlagsKHR"; + case BuiltInViewportMaskNV: return "ViewportMaskNV"; + case BuiltInSecondaryPositionNV: return "SecondaryPositionNV"; + case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV"; + case BuiltInPositionPerViewNV: return "PositionPerViewNV"; + case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV"; // case BuiltInFragmentSizeNV: return "FragmentSizeNV"; // superseded by BuiltInFragSizeEXT // case BuiltInInvocationsPerPixelNV: return "InvocationsPerPixelNV"; // superseded by BuiltInFragInvocationCountEXT - case BuiltInBaryCoordNV: return "BaryCoordNV"; - case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV"; + case BuiltInBaryCoordNV: return "BaryCoordNV"; + case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV"; - case BuiltInFragSizeEXT: return "FragSizeEXT"; - case BuiltInFragInvocationCountEXT: return "FragInvocationCountEXT"; + case BuiltInFragSizeEXT: return "FragSizeEXT"; + case BuiltInFragInvocationCountEXT: return "FragInvocationCountEXT"; case 5264: return "FullyCoveredEXT"; @@ -890,6 +911,9 @@ const char* CapabilityString(int info) case CapabilityPerViewAttributesNV: return "PerViewAttributesNV"; case CapabilityGroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV"; case CapabilityRayTracingNV: return "RayTracingNV"; + case CapabilityRayTracingProvisionalKHR: return "RayTracingProvisionalKHR"; + case CapabilityRayQueryProvisionalKHR: return "RayQueryProvisionalKHR"; + case CapabilityRayTraversalPrimitiveCullingProvisionalKHR: return "RayTraversalPrimitiveCullingProvisionalKHR"; case CapabilityComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV"; case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV"; case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV"; @@ -933,6 +957,9 @@ const char* CapabilityString(int info) case CapabilityIntegerFunctions2INTEL: return "CapabilityIntegerFunctions2INTEL"; + case CapabilityAtomicFloat32AddEXT: return "AtomicFloat32AddEXT"; + case CapabilityAtomicFloat64AddEXT: return "AtomicFloat64AddEXT"; + default: return "Bad"; } } @@ -1264,6 +1291,7 @@ const char* OpcodeString(int op) case 320: return "OpImageSparseRead"; case OpModuleProcessed: return "OpModuleProcessed"; + case OpExecutionModeId: return "OpExecutionModeId"; case OpDecorateId: return "OpDecorateId"; case 333: return "OpGroupNonUniformElect"; @@ -1308,6 +1336,8 @@ const char* OpcodeString(int op) case 4430: return "OpSubgroupAllEqualKHR"; case 4432: return "OpSubgroupReadInvocationKHR"; + case OpAtomicFAddEXT: return "OpAtomicFAddEXT"; + case 5000: return "OpGroupIAddNonUniformAMD"; case 5001: return "OpGroupFAddNonUniformAMD"; case 5002: return "OpGroupFMinNonUniformAMD"; @@ -1326,15 +1356,40 @@ const char* OpcodeString(int op) case OpMemberDecorateStringGOOGLE: return "OpMemberDecorateStringGOOGLE"; case OpGroupNonUniformPartitionNV: return "OpGroupNonUniformPartitionNV"; - case OpReportIntersectionNV: return "OpReportIntersectionNV"; - case OpIgnoreIntersectionNV: return "OpIgnoreIntersectionNV"; - case OpTerminateRayNV: return "OpTerminateRayNV"; - case OpTraceNV: return "OpTraceNV"; - case OpTypeAccelerationStructureNV: return "OpTypeAccelerationStructureNV"; - case OpExecuteCallableNV: return "OpExecuteCallableNV"; + case OpReportIntersectionKHR: return "OpReportIntersectionKHR"; + case OpIgnoreIntersectionKHR: return "OpIgnoreIntersectionKHR"; + case OpTerminateRayKHR: return "OpTerminateRayKHR"; + case OpTraceRayKHR: return "OpTraceRayKHR"; + case OpTypeAccelerationStructureKHR: return "OpTypeAccelerationStructureKHR"; + case OpExecuteCallableKHR: return "OpExecuteCallableKHR"; case OpImageSampleFootprintNV: return "OpImageSampleFootprintNV"; case OpWritePackedPrimitiveIndices4x8NV: return "OpWritePackedPrimitiveIndices4x8NV"; + case OpTypeRayQueryProvisionalKHR: return "OpTypeRayQueryProvisionalKHR"; + case OpRayQueryInitializeKHR: return "OpRayQueryInitializeKHR"; + case OpRayQueryTerminateKHR: return "OpRayQueryTerminateKHR"; + case OpRayQueryGenerateIntersectionKHR: return "OpRayQueryGenerateIntersectionKHR"; + case OpRayQueryConfirmIntersectionKHR: return "OpRayQueryConfirmIntersectionKHR"; + case OpRayQueryProceedKHR: return "OpRayQueryProceedKHR"; + case OpRayQueryGetIntersectionTypeKHR: return "OpRayQueryGetIntersectionTypeKHR"; + case OpRayQueryGetRayTMinKHR: return "OpRayQueryGetRayTMinKHR"; + case OpRayQueryGetRayFlagsKHR: return "OpRayQueryGetRayFlagsKHR"; + case OpRayQueryGetIntersectionTKHR: return "OpRayQueryGetIntersectionTKHR"; + case OpRayQueryGetIntersectionInstanceCustomIndexKHR: return "OpRayQueryGetIntersectionInstanceCustomIndexKHR"; + case OpRayQueryGetIntersectionInstanceIdKHR: return "OpRayQueryGetIntersectionInstanceIdKHR"; + case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: return "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR"; + case OpRayQueryGetIntersectionGeometryIndexKHR: return "OpRayQueryGetIntersectionGeometryIndexKHR"; + case OpRayQueryGetIntersectionPrimitiveIndexKHR: return "OpRayQueryGetIntersectionPrimitiveIndexKHR"; + case OpRayQueryGetIntersectionBarycentricsKHR: return "OpRayQueryGetIntersectionBarycentricsKHR"; + case OpRayQueryGetIntersectionFrontFaceKHR: return "OpRayQueryGetIntersectionFrontFaceKHR"; + case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: return "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR"; + case OpRayQueryGetIntersectionObjectRayDirectionKHR: return "OpRayQueryGetIntersectionObjectRayDirectionKHR"; + case OpRayQueryGetIntersectionObjectRayOriginKHR: return "OpRayQueryGetIntersectionObjectRayOriginKHR"; + case OpRayQueryGetWorldRayDirectionKHR: return "OpRayQueryGetWorldRayDirectionKHR"; + case OpRayQueryGetWorldRayOriginKHR: return "OpRayQueryGetWorldRayOriginKHR"; + case OpRayQueryGetIntersectionObjectToWorldKHR: return "OpRayQueryGetIntersectionObjectToWorldKHR"; + case OpRayQueryGetIntersectionWorldToObjectKHR: return "OpRayQueryGetIntersectionWorldToObjectKHR"; + case OpTypeCooperativeMatrixNV: return "OpTypeCooperativeMatrixNV"; case OpCooperativeMatrixLoadNV: return "OpCooperativeMatrixLoadNV"; case OpCooperativeMatrixStoreNV: return "OpCooperativeMatrixStoreNV"; @@ -1388,6 +1443,7 @@ void Parameterize() InstructionDesc[OpMemoryModel].setResultAndType(false, false); InstructionDesc[OpEntryPoint].setResultAndType(false, false); InstructionDesc[OpExecutionMode].setResultAndType(false, false); + InstructionDesc[OpExecutionModeId].setResultAndType(false, false); InstructionDesc[OpTypeVoid].setResultAndType(true, false); InstructionDesc[OpTypeBool].setResultAndType(true, false); InstructionDesc[OpTypeInt].setResultAndType(true, false); @@ -1574,6 +1630,10 @@ void Parameterize() InstructionDesc[OpExecutionMode].operands.push(OperandExecutionMode, "'Mode'"); InstructionDesc[OpExecutionMode].operands.push(OperandOptionalLiteral, "See <>"); + InstructionDesc[OpExecutionModeId].operands.push(OperandId, "'Entry Point'"); + InstructionDesc[OpExecutionModeId].operands.push(OperandExecutionMode, "'Mode'"); + InstructionDesc[OpExecutionModeId].operands.push(OperandVariableIds, "See <>"); + InstructionDesc[OpTypeInt].operands.push(OperandLiteralNumber, "'Width'"); InstructionDesc[OpTypeInt].operands.push(OperandLiteralNumber, "'Signedness'"); @@ -1667,7 +1727,7 @@ void Parameterize() InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandId, "'Target'"); InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandDecoration, ""); - InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandLiteralString, "'Literal String'"); + InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandVariableLiteralStrings, "'Literal Strings'"); InstructionDesc[OpMemberDecorate].operands.push(OperandId, "'Structure Type'"); InstructionDesc[OpMemberDecorate].operands.push(OperandLiteralNumber, "'Member'"); @@ -1677,7 +1737,7 @@ void Parameterize() InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandId, "'Structure Type'"); InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandLiteralNumber, "'Member'"); InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandDecoration, ""); - InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandLiteralString, "'Literal String'"); + InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandVariableLiteralStrings, "'Literal Strings'"); InstructionDesc[OpGroupDecorate].operands.push(OperandId, "'Decoration Group'"); InstructionDesc[OpGroupDecorate].operands.push(OperandVariableIds, "'Targets'"); @@ -2230,6 +2290,11 @@ void Parameterize() InstructionDesc[OpAtomicIAdd].operands.push(OperandMemorySemantics, "'Semantics'"); InstructionDesc[OpAtomicIAdd].operands.push(OperandId, "'Value'"); + InstructionDesc[OpAtomicFAddEXT].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicFAddEXT].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicFAddEXT].operands.push(OperandMemorySemantics, "'Semantics'"); + InstructionDesc[OpAtomicFAddEXT].operands.push(OperandId, "'Value'"); + InstructionDesc[OpAtomicISub].operands.push(OperandId, "'Pointer'"); InstructionDesc[OpAtomicISub].operands.push(OperandScope, "'Scope'"); InstructionDesc[OpAtomicISub].operands.push(OperandMemorySemantics, "'Semantics'"); @@ -2694,31 +2759,125 @@ void Parameterize() InstructionDesc[OpGroupNonUniformPartitionNV].operands.push(OperandId, "X"); - InstructionDesc[OpTypeAccelerationStructureNV].setResultAndType(true, false); + InstructionDesc[OpTypeAccelerationStructureKHR].setResultAndType(true, false); - InstructionDesc[OpTraceNV].operands.push(OperandId, "'NV Acceleration Structure'"); - InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Flags'"); - InstructionDesc[OpTraceNV].operands.push(OperandId, "'Cull Mask'"); - InstructionDesc[OpTraceNV].operands.push(OperandId, "'SBT Record Offset'"); - InstructionDesc[OpTraceNV].operands.push(OperandId, "'SBT Record Stride'"); - InstructionDesc[OpTraceNV].operands.push(OperandId, "'Miss Index'"); - InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Origin'"); - InstructionDesc[OpTraceNV].operands.push(OperandId, "'TMin'"); - InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Direction'"); - InstructionDesc[OpTraceNV].operands.push(OperandId, "'TMax'"); - InstructionDesc[OpTraceNV].operands.push(OperandId, "'Payload'"); - InstructionDesc[OpTraceNV].setResultAndType(false, false); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'NV Acceleration Structure'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Flags'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Cull Mask'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'SBT Record Offset'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'SBT Record Stride'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Miss Index'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Origin'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'TMin'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Direction'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'TMax'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Payload'"); + InstructionDesc[OpTraceRayKHR].setResultAndType(false, false); - InstructionDesc[OpReportIntersectionNV].operands.push(OperandId, "'Hit Parameter'"); - InstructionDesc[OpReportIntersectionNV].operands.push(OperandId, "'Hit Kind'"); + InstructionDesc[OpReportIntersectionKHR].operands.push(OperandId, "'Hit Parameter'"); + InstructionDesc[OpReportIntersectionKHR].operands.push(OperandId, "'Hit Kind'"); - InstructionDesc[OpIgnoreIntersectionNV].setResultAndType(false, false); + InstructionDesc[OpIgnoreIntersectionKHR].setResultAndType(false, false); - InstructionDesc[OpTerminateRayNV].setResultAndType(false, false); + InstructionDesc[OpTerminateRayKHR].setResultAndType(false, false); - InstructionDesc[OpExecuteCallableNV].operands.push(OperandId, "SBT Record Index"); - InstructionDesc[OpExecuteCallableNV].operands.push(OperandId, "CallableData ID"); - InstructionDesc[OpExecuteCallableNV].setResultAndType(false, false); + InstructionDesc[OpExecuteCallableKHR].operands.push(OperandId, "SBT Record Index"); + InstructionDesc[OpExecuteCallableKHR].operands.push(OperandId, "CallableData ID"); + InstructionDesc[OpExecuteCallableKHR].setResultAndType(false, false); + + // Ray Query + InstructionDesc[OpTypeAccelerationStructureKHR].setResultAndType(true, false); + InstructionDesc[OpTypeRayQueryProvisionalKHR].setResultAndType(true, false); + + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'AccelerationS'"); + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'RayFlags'"); + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'CullMask'"); + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Origin'"); + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Tmin'"); + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Direction'"); + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Tmax'"); + InstructionDesc[OpRayQueryInitializeKHR].setResultAndType(false, false); + + InstructionDesc[OpRayQueryTerminateKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryTerminateKHR].setResultAndType(false, false); + + InstructionDesc[OpRayQueryGenerateIntersectionKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGenerateIntersectionKHR].operands.push(OperandId, "'THit'"); + InstructionDesc[OpRayQueryGenerateIntersectionKHR].setResultAndType(false, false); + + InstructionDesc[OpRayQueryConfirmIntersectionKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryConfirmIntersectionKHR].setResultAndType(false, false); + + InstructionDesc[OpRayQueryProceedKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryProceedKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionTypeKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionTypeKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionTypeKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetRayTMinKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetRayTMinKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetRayFlagsKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetRayFlagsKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionTKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionTKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionTKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionInstanceCustomIndexKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionInstanceCustomIndexKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionInstanceCustomIndexKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionInstanceIdKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionInstanceIdKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionInstanceIdKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionGeometryIndexKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionGeometryIndexKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionGeometryIndexKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionPrimitiveIndexKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionPrimitiveIndexKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionPrimitiveIndexKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionBarycentricsKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionBarycentricsKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionBarycentricsKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionFrontFaceKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionFrontFaceKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionFrontFaceKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionCandidateAABBOpaqueKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionCandidateAABBOpaqueKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionObjectRayDirectionKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionObjectRayDirectionKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionObjectRayDirectionKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionObjectRayOriginKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionObjectRayOriginKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionObjectRayOriginKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetWorldRayDirectionKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetWorldRayDirectionKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetWorldRayOriginKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetWorldRayOriginKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionObjectToWorldKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionObjectToWorldKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionObjectToWorldKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionWorldToObjectKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionWorldToObjectKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionWorldToObjectKHR].setResultAndType(true, true); InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Sampled Image'"); InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Coordinate'"); diff --git a/src/libraries/glslang/SPIRV/doc.h b/src/libraries/glslang/SPIRV/doc.h index 293256a2c..2a0b28c6b 100644 --- a/src/libraries/glslang/SPIRV/doc.h +++ b/src/libraries/glslang/SPIRV/doc.h @@ -125,6 +125,7 @@ enum OperandClass { OperandVariableLiteralId, OperandLiteralNumber, OperandLiteralString, + OperandVariableLiteralStrings, OperandSource, OperandExecutionModel, OperandAddressing, diff --git a/src/libraries/glslang/SPIRV/hex_float.h b/src/libraries/glslang/SPIRV/hex_float.h index 905b21a45..8be8e9f7e 100644 --- a/src/libraries/glslang/SPIRV/hex_float.h +++ b/src/libraries/glslang/SPIRV/hex_float.h @@ -784,8 +784,8 @@ inline std::istream& ParseNormalFloat(std::istream& is, bool negate_value, if (val.isInfinity()) { // Fail the parse. Emulate standard behaviour by setting the value to // the closest normal value, and set the fail bit on the stream. - value.set_value((value.isNegative() | negate_value) ? T::lowest() - : T::max()); + value.set_value((value.isNegative() || negate_value) ? T::lowest() + : T::max()); is.setstate(std::ios_base::failbit); } return is; diff --git a/src/libraries/glslang/SPIRV/spirv.hpp b/src/libraries/glslang/SPIRV/spirv.hpp index 1e96f7b4a..35482ea5e 100644 --- a/src/libraries/glslang/SPIRV/spirv.hpp +++ b/src/libraries/glslang/SPIRV/spirv.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2019 The Khronos Group Inc. +// Copyright (c) 2014-2020 The Khronos Group Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and/or associated documentation files (the "Materials"), @@ -49,12 +49,12 @@ namespace spv { typedef unsigned int Id; -#define SPV_VERSION 0x10400 -#define SPV_REVISION 1 +#define SPV_VERSION 0x10500 +#define SPV_REVISION 3 static const unsigned int MagicNumber = 0x07230203; -static const unsigned int Version = 0x00010400; -static const unsigned int Revision = 1; +static const unsigned int Version = 0x00010500; +static const unsigned int Revision = 3; static const unsigned int OpCodeMask = 0xffff; static const unsigned int WordCountShift = 16; @@ -78,11 +78,17 @@ enum ExecutionModel { ExecutionModelKernel = 6, ExecutionModelTaskNV = 5267, ExecutionModelMeshNV = 5268, + ExecutionModelRayGenerationKHR = 5313, ExecutionModelRayGenerationNV = 5313, + ExecutionModelIntersectionKHR = 5314, ExecutionModelIntersectionNV = 5314, + ExecutionModelAnyHitKHR = 5315, ExecutionModelAnyHitNV = 5315, + ExecutionModelClosestHitKHR = 5316, ExecutionModelClosestHitNV = 5316, + ExecutionModelMissKHR = 5317, ExecutionModelMissNV = 5317, + ExecutionModelCallableKHR = 5318, ExecutionModelCallableNV = 5318, ExecutionModelMax = 0x7fffffff, }; @@ -162,6 +168,10 @@ enum ExecutionMode { ExecutionModeSampleInterlockUnorderedEXT = 5369, ExecutionModeShadingRateInterlockOrderedEXT = 5370, ExecutionModeShadingRateInterlockUnorderedEXT = 5371, + ExecutionModeMaxWorkgroupSizeINTEL = 5893, + ExecutionModeMaxWorkDimINTEL = 5894, + ExecutionModeNoGlobalOffsetINTEL = 5895, + ExecutionModeNumSIMDWorkitemsINTEL = 5896, ExecutionModeMax = 0x7fffffff, }; @@ -179,14 +189,21 @@ enum StorageClass { StorageClassAtomicCounter = 10, StorageClassImage = 11, StorageClassStorageBuffer = 12, + StorageClassCallableDataKHR = 5328, StorageClassCallableDataNV = 5328, + StorageClassIncomingCallableDataKHR = 5329, StorageClassIncomingCallableDataNV = 5329, + StorageClassRayPayloadKHR = 5338, StorageClassRayPayloadNV = 5338, + StorageClassHitAttributeKHR = 5339, StorageClassHitAttributeNV = 5339, + StorageClassIncomingRayPayloadKHR = 5342, StorageClassIncomingRayPayloadNV = 5342, + StorageClassShaderRecordBufferKHR = 5343, StorageClassShaderRecordBufferNV = 5343, StorageClassPhysicalStorageBuffer = 5349, StorageClassPhysicalStorageBufferEXT = 5349, + StorageClassCodeSectionINTEL = 5605, StorageClassMax = 0x7fffffff, }; @@ -465,11 +482,24 @@ enum Decoration { DecorationRestrictPointerEXT = 5355, DecorationAliasedPointer = 5356, DecorationAliasedPointerEXT = 5356, + DecorationReferencedIndirectlyINTEL = 5602, DecorationCounterBuffer = 5634, DecorationHlslCounterBufferGOOGLE = 5634, DecorationHlslSemanticGOOGLE = 5635, DecorationUserSemantic = 5635, DecorationUserTypeGOOGLE = 5636, + DecorationRegisterINTEL = 5825, + DecorationMemoryINTEL = 5826, + DecorationNumbanksINTEL = 5827, + DecorationBankwidthINTEL = 5828, + DecorationMaxPrivateCopiesINTEL = 5829, + DecorationSinglepumpINTEL = 5830, + DecorationDoublepumpINTEL = 5831, + DecorationMaxReplicatesINTEL = 5832, + DecorationSimpleDualPortINTEL = 5833, + DecorationMergeINTEL = 5834, + DecorationBankBitsINTEL = 5835, + DecorationForcePow2DepthINTEL = 5836, DecorationMax = 0x7fffffff, }; @@ -558,20 +588,35 @@ enum BuiltIn { BuiltInFragmentSizeNV = 5292, BuiltInFragInvocationCountEXT = 5293, BuiltInInvocationsPerPixelNV = 5293, + BuiltInLaunchIdKHR = 5319, BuiltInLaunchIdNV = 5319, + BuiltInLaunchSizeKHR = 5320, BuiltInLaunchSizeNV = 5320, + BuiltInWorldRayOriginKHR = 5321, BuiltInWorldRayOriginNV = 5321, + BuiltInWorldRayDirectionKHR = 5322, BuiltInWorldRayDirectionNV = 5322, + BuiltInObjectRayOriginKHR = 5323, BuiltInObjectRayOriginNV = 5323, + BuiltInObjectRayDirectionKHR = 5324, BuiltInObjectRayDirectionNV = 5324, + BuiltInRayTminKHR = 5325, BuiltInRayTminNV = 5325, + BuiltInRayTmaxKHR = 5326, BuiltInRayTmaxNV = 5326, + BuiltInInstanceCustomIndexKHR = 5327, BuiltInInstanceCustomIndexNV = 5327, + BuiltInObjectToWorldKHR = 5330, BuiltInObjectToWorldNV = 5330, + BuiltInWorldToObjectKHR = 5331, BuiltInWorldToObjectNV = 5331, + BuiltInHitTKHR = 5332, BuiltInHitTNV = 5332, + BuiltInHitKindKHR = 5333, BuiltInHitKindNV = 5333, + BuiltInIncomingRayFlagsKHR = 5351, BuiltInIncomingRayFlagsNV = 5351, + BuiltInRayGeometryIndexKHR = 5352, BuiltInWarpsPerSMNV = 5374, BuiltInSMCountNV = 5375, BuiltInWarpIDNV = 5376, @@ -601,6 +646,13 @@ enum LoopControlShift { LoopControlIterationMultipleShift = 6, LoopControlPeelCountShift = 7, LoopControlPartialCountShift = 8, + LoopControlInitiationIntervalINTELShift = 16, + LoopControlMaxConcurrencyINTELShift = 17, + LoopControlDependencyArrayINTELShift = 18, + LoopControlPipelineEnableINTELShift = 19, + LoopControlLoopCoalesceINTELShift = 20, + LoopControlMaxInterleavingINTELShift = 21, + LoopControlSpeculatedIterationsINTELShift = 22, LoopControlMax = 0x7fffffff, }; @@ -615,6 +667,13 @@ enum LoopControlMask { LoopControlIterationMultipleMask = 0x00000040, LoopControlPeelCountMask = 0x00000080, LoopControlPartialCountMask = 0x00000100, + LoopControlInitiationIntervalINTELMask = 0x00010000, + LoopControlMaxConcurrencyINTELMask = 0x00020000, + LoopControlDependencyArrayINTELMask = 0x00040000, + LoopControlPipelineEnableINTELMask = 0x00080000, + LoopControlLoopCoalesceINTELMask = 0x00100000, + LoopControlMaxInterleavingINTELMask = 0x00200000, + LoopControlSpeculatedIterationsINTELMask = 0x00400000, }; enum FunctionControlShift { @@ -709,6 +768,7 @@ enum Scope { ScopeInvocation = 4, ScopeQueueFamily = 5, ScopeQueueFamilyKHR = 5, + ScopeShaderCallKHR = 6, ScopeMax = 0x7fffffff, }; @@ -833,6 +893,8 @@ enum Capability { CapabilitySignedZeroInfNanPreserve = 4466, CapabilityRoundingModeRTE = 4467, CapabilityRoundingModeRTZ = 4468, + CapabilityRayQueryProvisionalKHR = 4471, + CapabilityRayTraversalPrimitiveCullingProvisionalKHR = 4478, CapabilityFloat16ImageAMD = 5008, CapabilityImageGatherBiasLodAMD = 5009, CapabilityFragmentMaskAMD = 5010, @@ -886,6 +948,7 @@ enum Capability { CapabilityPhysicalStorageBufferAddresses = 5347, CapabilityPhysicalStorageBufferAddressesEXT = 5347, CapabilityComputeDerivativeGroupLinearNV = 5350, + CapabilityRayTracingProvisionalKHR = 5353, CapabilityCooperativeMatrixNV = 5357, CapabilityFragmentShaderSampleInterlockEXT = 5363, CapabilityFragmentShaderShadingRateInterlockEXT = 5372, @@ -897,12 +960,70 @@ enum Capability { CapabilitySubgroupImageBlockIOINTEL = 5570, CapabilitySubgroupImageMediaBlockIOINTEL = 5579, CapabilityIntegerFunctions2INTEL = 5584, + CapabilityFunctionPointersINTEL = 5603, + CapabilityIndirectReferencesINTEL = 5604, CapabilitySubgroupAvcMotionEstimationINTEL = 5696, CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697, CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698, + CapabilityFPGAMemoryAttributesINTEL = 5824, + CapabilityUnstructuredLoopControlsINTEL = 5886, + CapabilityFPGALoopControlsINTEL = 5888, + CapabilityKernelAttributesINTEL = 5892, + CapabilityFPGAKernelAttributesINTEL = 5897, + CapabilityBlockingPipesINTEL = 5945, + CapabilityFPGARegINTEL = 5948, + CapabilityAtomicFloat32AddEXT = 6033, + CapabilityAtomicFloat64AddEXT = 6034, CapabilityMax = 0x7fffffff, }; +enum RayFlagsShift { + RayFlagsOpaqueKHRShift = 0, + RayFlagsNoOpaqueKHRShift = 1, + RayFlagsTerminateOnFirstHitKHRShift = 2, + RayFlagsSkipClosestHitShaderKHRShift = 3, + RayFlagsCullBackFacingTrianglesKHRShift = 4, + RayFlagsCullFrontFacingTrianglesKHRShift = 5, + RayFlagsCullOpaqueKHRShift = 6, + RayFlagsCullNoOpaqueKHRShift = 7, + RayFlagsSkipTrianglesKHRShift = 8, + RayFlagsSkipAABBsKHRShift = 9, + RayFlagsMax = 0x7fffffff, +}; + +enum RayFlagsMask { + RayFlagsMaskNone = 0, + RayFlagsOpaqueKHRMask = 0x00000001, + RayFlagsNoOpaqueKHRMask = 0x00000002, + RayFlagsTerminateOnFirstHitKHRMask = 0x00000004, + RayFlagsSkipClosestHitShaderKHRMask = 0x00000008, + RayFlagsCullBackFacingTrianglesKHRMask = 0x00000010, + RayFlagsCullFrontFacingTrianglesKHRMask = 0x00000020, + RayFlagsCullOpaqueKHRMask = 0x00000040, + RayFlagsCullNoOpaqueKHRMask = 0x00000080, + RayFlagsSkipTrianglesKHRMask = 0x00000100, + RayFlagsSkipAABBsKHRMask = 0x00000200, +}; + +enum RayQueryIntersection { + RayQueryIntersectionRayQueryCandidateIntersectionKHR = 0, + RayQueryIntersectionRayQueryCommittedIntersectionKHR = 1, + RayQueryIntersectionMax = 0x7fffffff, +}; + +enum RayQueryCommittedIntersectionType { + RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR = 0, + RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR = 1, + RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR = 2, + RayQueryCommittedIntersectionTypeMax = 0x7fffffff, +}; + +enum RayQueryCandidateIntersectionType { + RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR = 0, + RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR = 1, + RayQueryCandidateIntersectionTypeMax = 0x7fffffff, +}; + enum Op { OpNop = 0, OpUndef = 1, @@ -1254,6 +1375,13 @@ enum Op { OpSubgroupAnyKHR = 4429, OpSubgroupAllEqualKHR = 4430, OpSubgroupReadInvocationKHR = 4432, + OpTypeRayQueryProvisionalKHR = 4472, + OpRayQueryInitializeKHR = 4473, + OpRayQueryTerminateKHR = 4474, + OpRayQueryGenerateIntersectionKHR = 4475, + OpRayQueryConfirmIntersectionKHR = 4476, + OpRayQueryProceedKHR = 4477, + OpRayQueryGetIntersectionTypeKHR = 4479, OpGroupIAddNonUniformAMD = 5000, OpGroupFAddNonUniformAMD = 5001, OpGroupFMinNonUniformAMD = 5002, @@ -1268,11 +1396,17 @@ enum Op { OpImageSampleFootprintNV = 5283, OpGroupNonUniformPartitionNV = 5296, OpWritePackedPrimitiveIndices4x8NV = 5299, + OpReportIntersectionKHR = 5334, OpReportIntersectionNV = 5334, + OpIgnoreIntersectionKHR = 5335, OpIgnoreIntersectionNV = 5335, + OpTerminateRayKHR = 5336, OpTerminateRayNV = 5336, OpTraceNV = 5337, + OpTraceRayKHR = 5337, + OpTypeAccelerationStructureKHR = 5341, OpTypeAccelerationStructureNV = 5341, + OpExecuteCallableKHR = 5344, OpExecuteCallableNV = 5344, OpTypeCooperativeMatrixNV = 5358, OpCooperativeMatrixLoadNV = 5359, @@ -1307,6 +1441,8 @@ enum Op { OpUSubSatINTEL = 5596, OpIMul32x16INTEL = 5597, OpUMul32x16INTEL = 5598, + OpFunctionPointerINTEL = 5600, + OpFunctionPointerCallINTEL = 5601, OpDecorateString = 5632, OpDecorateStringGOOGLE = 5632, OpMemberDecorateString = 5633, @@ -1429,6 +1565,28 @@ enum Op { OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + OpLoopControlINTEL = 5887, + OpReadPipeBlockingINTEL = 5946, + OpWritePipeBlockingINTEL = 5947, + OpFPGARegINTEL = 5949, + OpRayQueryGetRayTMinKHR = 6016, + OpRayQueryGetRayFlagsKHR = 6017, + OpRayQueryGetIntersectionTKHR = 6018, + OpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, + OpRayQueryGetIntersectionInstanceIdKHR = 6020, + OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, + OpRayQueryGetIntersectionGeometryIndexKHR = 6022, + OpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, + OpRayQueryGetIntersectionBarycentricsKHR = 6024, + OpRayQueryGetIntersectionFrontFaceKHR = 6025, + OpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, + OpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, + OpRayQueryGetIntersectionObjectRayOriginKHR = 6028, + OpRayQueryGetWorldRayDirectionKHR = 6029, + OpRayQueryGetWorldRayOriginKHR = 6030, + OpRayQueryGetIntersectionObjectToWorldKHR = 6031, + OpRayQueryGetIntersectionWorldToObjectKHR = 6032, + OpAtomicFAddEXT = 6035, OpMax = 0x7fffffff, }; @@ -1787,6 +1945,13 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break; case OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break; case OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break; + case OpTypeRayQueryProvisionalKHR: *hasResult = true; *hasResultType = false; break; + case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryConfirmIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryProceedKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionTypeKHR: *hasResult = true; *hasResultType = true; break; case OpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; case OpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; case OpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; @@ -1840,6 +2005,8 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break; case OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break; case OpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case OpFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break; + case OpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break; case OpDecorateString: *hasResult = false; *hasResultType = false; break; case OpMemberDecorateString: *hasResult = false; *hasResultType = false; break; case OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break; @@ -1960,6 +2127,28 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break; case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break; case OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break; + case OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break; + case OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case OpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case OpFPGARegINTEL: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionInstanceCustomIndexKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionInstanceIdKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionGeometryIndexKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionPrimitiveIndexKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionBarycentricsKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionFrontFaceKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionObjectRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionObjectRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetWorldRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break; + case OpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break; } } #endif /* SPV_ENABLE_UTILITY_CODE */ @@ -1974,6 +2163,7 @@ inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } +inline RayFlagsMask operator|(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) | unsigned(b)); } } // end namespace spv diff --git a/src/libraries/glslang/SPIRV/spvIR.h b/src/libraries/glslang/SPIRV/spvIR.h old mode 100755 new mode 100644 index cf6a71159..868b9bf82 --- a/src/libraries/glslang/SPIRV/spvIR.h +++ b/src/libraries/glslang/SPIRV/spvIR.h @@ -55,6 +55,7 @@ #include #include #include +#include namespace spv { @@ -235,8 +236,7 @@ public: assert(instructions.size() > 0); instructions.resize(1); successors.clear(); - Instruction* unreachable = new Instruction(OpUnreachable); - addInstruction(std::unique_ptr(unreachable)); + addInstruction(std::unique_ptr(new Instruction(OpUnreachable))); } // Change this block into a canonical dead continue target branching to the // given header ID. Delete instructions as necessary. A canonical dead continue @@ -352,10 +352,28 @@ public: const std::vector& getBlocks() const { return blocks; } void addLocalVariable(std::unique_ptr inst); Id getReturnType() const { return functionInstruction.getTypeId(); } + void setReturnPrecision(Decoration precision) + { + if (precision == DecorationRelaxedPrecision) + reducedPrecisionReturn = true; + } + Decoration getReturnPrecision() const + { return reducedPrecisionReturn ? DecorationRelaxedPrecision : NoPrecision; } void setImplicitThis() { implicitThis = true; } bool hasImplicitThis() const { return implicitThis; } + void addParamPrecision(unsigned param, Decoration precision) + { + if (precision == DecorationRelaxedPrecision) + reducedPrecisionParams.insert(param); + } + Decoration getParamPrecision(unsigned param) const + { + return reducedPrecisionParams.find(param) != reducedPrecisionParams.end() ? + DecorationRelaxedPrecision : NoPrecision; + } + void dump(std::vector& out) const { // OpFunction @@ -380,6 +398,8 @@ protected: std::vector parameterInstructions; std::vector blocks; bool implicitThis; // true if this is a member function expecting to be passed a 'this' as the first argument + bool reducedPrecisionReturn; + std::set reducedPrecisionParams; // list of parameter indexes that need a relaxed precision arg }; // @@ -440,7 +460,8 @@ protected: // - the OpFunction instruction // - all the OpFunctionParameter instructions __inline Function::Function(Id id, Id resultType, Id functionType, Id firstParamId, Module& parent) - : parent(parent), functionInstruction(id, resultType, OpFunction), implicitThis(false) + : parent(parent), functionInstruction(id, resultType, OpFunction), implicitThis(false), + reducedPrecisionReturn(false) { // OpFunction functionInstruction.addImmediateOperand(FunctionControlMaskNone); diff --git a/src/libraries/glslang/glslang/Include/BaseTypes.h b/src/libraries/glslang/glslang/Include/BaseTypes.h index 6d4b4ff8e..b69eaebf2 100644 --- a/src/libraries/glslang/glslang/Include/BaseTypes.h +++ b/src/libraries/glslang/glslang/Include/BaseTypes.h @@ -2,6 +2,7 @@ // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2013 LunarG, Inc. // Copyright (C) 2017 ARM Limited. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -61,8 +62,9 @@ enum TBasicType { EbtSampler, EbtStruct, EbtBlock, - EbtAccStructNV, + EbtAccStruct, EbtReference, + EbtRayQuery, // HLSL types that live only temporarily. EbtString, @@ -90,11 +92,11 @@ enum TStorageQualifier { EvqBuffer, // read/write, shared with app EvqShared, // compute shader's read/write 'shared' qualifier - EvqPayloadNV, - EvqPayloadInNV, - EvqHitAttrNV, - EvqCallableDataNV, - EvqCallableDataInNV, + EvqPayload, + EvqPayloadIn, + EvqHitAttr, + EvqCallableData, + EvqCallableDataIn, // parameters EvqIn, // also, for 'in' in the grammar before we know if it's a pipeline input or an 'in' parameter @@ -229,6 +231,9 @@ enum TBuiltInVariable { EbvFragSizeEXT, EbvFragInvocationCountEXT, + EbvSecondaryFragDataEXT, + EbvSecondaryFragColorEXT, + EbvViewportMaskNV, EbvSecondaryPositionNV, EbvSecondaryViewportMaskNV, @@ -238,20 +243,23 @@ enum TBuiltInVariable { EbvFragmentSizeNV, EbvInvocationsPerPixelNV, // ray tracing - EbvLaunchIdNV, - EbvLaunchSizeNV, - EbvInstanceCustomIndexNV, - EbvWorldRayOriginNV, - EbvWorldRayDirectionNV, - EbvObjectRayOriginNV, - EbvObjectRayDirectionNV, - EbvRayTminNV, - EbvRayTmaxNV, - EbvHitTNV, - EbvHitKindNV, - EbvObjectToWorldNV, - EbvWorldToObjectNV, - EbvIncomingRayFlagsNV, + EbvLaunchId, + EbvLaunchSize, + EbvInstanceCustomIndex, + EbvGeometryIndex, + EbvWorldRayOrigin, + EbvWorldRayDirection, + EbvObjectRayOrigin, + EbvObjectRayDirection, + EbvRayTmin, + EbvRayTmax, + EbvHitT, + EbvHitKind, + EbvObjectToWorld, + EbvObjectToWorld3x4, + EbvWorldToObject, + EbvWorldToObject3x4, + EbvIncomingRayFlags, // barycentrics EbvBaryCoordNV, EbvBaryCoordNoPerspNV, @@ -328,11 +336,11 @@ __inline const char* GetStorageQualifierString(TStorageQualifier q) case EvqPointCoord: return "gl_PointCoord"; break; case EvqFragColor: return "fragColor"; break; case EvqFragDepth: return "gl_FragDepth"; break; - case EvqPayloadNV: return "rayPayloadNV"; break; - case EvqPayloadInNV: return "rayPayloadInNV"; break; - case EvqHitAttrNV: return "hitAttributeNV"; break; - case EvqCallableDataNV: return "callableDataNV"; break; - case EvqCallableDataInNV: return "callableDataInNV"; break; + case EvqPayload: return "rayPayloadNV"; break; + case EvqPayloadIn: return "rayPayloadInNV"; break; + case EvqHitAttr: return "hitAttributeNV"; break; + case EvqCallableData: return "callableDataNV"; break; + case EvqCallableDataIn: return "callableDataInNV"; break; default: return "unknown qualifier"; } } @@ -428,6 +436,9 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v) case EbvFragSizeEXT: return "FragSizeEXT"; case EbvFragInvocationCountEXT: return "FragInvocationCountEXT"; + case EbvSecondaryFragDataEXT: return "SecondaryFragDataEXT"; + case EbvSecondaryFragColorEXT: return "SecondaryFragColorEXT"; + case EbvViewportMaskNV: return "ViewportMaskNV"; case EbvSecondaryPositionNV: return "SecondaryPositionNV"; case EbvSecondaryViewportMaskNV: return "SecondaryViewportMaskNV"; @@ -436,20 +447,21 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v) case EbvFragFullyCoveredNV: return "FragFullyCoveredNV"; case EbvFragmentSizeNV: return "FragmentSizeNV"; case EbvInvocationsPerPixelNV: return "InvocationsPerPixelNV"; - case EbvLaunchIdNV: return "LaunchIdNV"; - case EbvLaunchSizeNV: return "LaunchSizeNV"; - case EbvInstanceCustomIndexNV: return "InstanceCustomIndexNV"; - case EbvWorldRayOriginNV: return "WorldRayOriginNV"; - case EbvWorldRayDirectionNV: return "WorldRayDirectionNV"; - case EbvObjectRayOriginNV: return "ObjectRayOriginNV"; - case EbvObjectRayDirectionNV: return "ObjectRayDirectionNV"; - case EbvRayTminNV: return "ObjectRayTminNV"; - case EbvRayTmaxNV: return "ObjectRayTmaxNV"; - case EbvHitTNV: return "HitTNV"; - case EbvHitKindNV: return "HitKindNV"; - case EbvIncomingRayFlagsNV: return "IncomingRayFlagsNV"; - case EbvObjectToWorldNV: return "ObjectToWorldNV"; - case EbvWorldToObjectNV: return "WorldToObjectNV"; + case EbvLaunchId: return "LaunchIdNV"; + case EbvLaunchSize: return "LaunchSizeNV"; + case EbvInstanceCustomIndex: return "InstanceCustomIndexNV"; + case EbvGeometryIndex: return "GeometryIndexEXT"; + case EbvWorldRayOrigin: return "WorldRayOriginNV"; + case EbvWorldRayDirection: return "WorldRayDirectionNV"; + case EbvObjectRayOrigin: return "ObjectRayOriginNV"; + case EbvObjectRayDirection: return "ObjectRayDirectionNV"; + case EbvRayTmin: return "ObjectRayTminNV"; + case EbvRayTmax: return "ObjectRayTmaxNV"; + case EbvHitT: return "HitTNV"; + case EbvHitKind: return "HitKindNV"; + case EbvIncomingRayFlags: return "IncomingRayFlagsNV"; + case EbvObjectToWorld: return "ObjectToWorldNV"; + case EbvWorldToObject: return "WorldToObjectNV"; case EbvBaryCoordNV: return "BaryCoordNV"; case EbvBaryCoordNoPerspNV: return "BaryCoordNoPerspNV"; diff --git a/src/libraries/glslang/glslang/Include/Common.h b/src/libraries/glslang/glslang/Include/Common.h index 733a790cf..b628cdc2f 100644 --- a/src/libraries/glslang/glslang/Include/Common.h +++ b/src/libraries/glslang/glslang/Include/Common.h @@ -37,6 +37,17 @@ #ifndef _COMMON_INCLUDED_ #define _COMMON_INCLUDED_ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #if defined(__ANDROID__) || (defined(_MSC_VER) && _MSC_VER < 1700) #include @@ -93,18 +104,6 @@ std::string to_string(const T& val) { #pragma warning(disable : 4201) // nameless union #endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include "PoolAlloc.h" // diff --git a/src/libraries/glslang/glslang/Include/ConstantUnion.h b/src/libraries/glslang/glslang/Include/ConstantUnion.h index 76b2d9c08..c4ffb8577 100644 --- a/src/libraries/glslang/glslang/Include/ConstantUnion.h +++ b/src/libraries/glslang/glslang/Include/ConstantUnion.h @@ -921,7 +921,7 @@ public: else unionArray = new TConstUnionVector(size); } - TConstUnionArray(const TConstUnionArray& a) : unionArray(a.unionArray) { } + TConstUnionArray(const TConstUnionArray& a) = default; TConstUnionArray(const TConstUnionArray& a, int start, int size) { unionArray = new TConstUnionVector(size); diff --git a/src/libraries/glslang/glslang/Include/ResourceLimits.h b/src/libraries/glslang/glslang/Include/ResourceLimits.h index 106b21d9c..b670cf163 100644 --- a/src/libraries/glslang/glslang/Include/ResourceLimits.h +++ b/src/libraries/glslang/glslang/Include/ResourceLimits.h @@ -142,6 +142,7 @@ struct TBuiltInResource { int maxTaskWorkGroupSizeY_NV; int maxTaskWorkGroupSizeZ_NV; int maxMeshViewCountNV; + int maxDualSourceDrawBuffersEXT; TLimits limits; }; diff --git a/src/libraries/glslang/glslang/Include/Types.h b/src/libraries/glslang/glslang/Include/Types.h index 3572099e3..235ea3f1d 100644 --- a/src/libraries/glslang/glslang/Include/Types.h +++ b/src/libraries/glslang/glslang/Include/Types.h @@ -3,6 +3,7 @@ // Copyright (C) 2012-2016 LunarG, Inc. // Copyright (C) 2015-2016 Google, Inc. // Copyright (C) 2017 ARM Limited. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -472,6 +473,18 @@ enum TInterlockOrdering { EioCount, }; +enum TShaderInterface +{ + // Includes both uniform blocks and buffer blocks + EsiUniform = 0, + EsiInput, + EsiOutput, + EsiNone, + + EsiCount +}; + + class TQualifier { public: static const int layoutNotSet = -1; @@ -532,6 +545,7 @@ public: queuefamilycoherent = false; workgroupcoherent = false; subgroupcoherent = false; + shadercallcoherent = false; nonprivate = false; volatil = false; restrict = false; @@ -553,6 +567,7 @@ public: // having a constant_id is not sufficient: expressions have no id, but are still specConstant bool specConstant : 1; bool nonUniform : 1; + bool explicitOffset : 1; #ifdef GLSLANG_WEB bool isWriteOnly() const { return false; } @@ -590,6 +605,7 @@ public: bool queuefamilycoherent : 1; bool workgroupcoherent : 1; bool subgroupcoherent : 1; + bool shadercallcoherent : 1; bool nonprivate : 1; bool isWriteOnly() const { return writeonly; } bool isReadOnly() const { return readonly; } @@ -599,11 +615,11 @@ public: bool isSample() const { return sample; } bool isMemory() const { - return subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || volatil || restrict || readonly || writeonly || nonprivate; + return shadercallcoherent || subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || volatil || restrict || readonly || writeonly || nonprivate; } bool isMemoryQualifierImageAndSSBOOnly() const { - return subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || volatil || restrict || readonly || writeonly; + return shadercallcoherent || subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || volatil || restrict || readonly || writeonly; } bool bufferReferenceNeedsVulkanMemoryModel() const { @@ -773,7 +789,7 @@ public: layoutViewportRelative = false; // -2048 as the default value indicating layoutSecondaryViewportRelative is not set layoutSecondaryViewportRelativeOffset = -2048; - layoutShaderRecordNV = false; + layoutShaderRecord = false; layoutBufferReferenceAlign = layoutBufferReferenceAlignEnd; layoutFormat = ElfNone; #endif @@ -812,7 +828,7 @@ public: hasAnyLocation() || hasStream() || hasFormat() || - isShaderRecordNV() || + isShaderRecord() || isPushConstant() || hasBufferReference(); } @@ -871,7 +887,7 @@ public: bool layoutPassthrough; bool layoutViewportRelative; int layoutSecondaryViewportRelativeOffset; - bool layoutShaderRecordNV; + bool layoutShaderRecord; #endif bool hasUniformLayout() const @@ -942,7 +958,7 @@ public: bool hasAttachment() const { return false; } TLayoutFormat getFormat() const { return ElfNone; } bool isPushConstant() const { return false; } - bool isShaderRecordNV() const { return false; } + bool isShaderRecord() const { return false; } bool hasBufferReference() const { return false; } bool hasBufferReferenceAlign() const { return false; } bool isNonUniform() const { return false; } @@ -993,7 +1009,7 @@ public: } TLayoutFormat getFormat() const { return layoutFormat; } bool isPushConstant() const { return layoutPushConstant; } - bool isShaderRecordNV() const { return layoutShaderRecordNV; } + bool isShaderRecord() const { return layoutShaderRecord; } bool hasBufferReference() const { return layoutBufferReference; } bool hasBufferReferenceAlign() const { @@ -1219,6 +1235,7 @@ struct TShaderQualifiers { bool layoutDerivativeGroupQuads; // true if layout derivative_group_quadsNV set bool layoutDerivativeGroupLinear; // true if layout derivative_group_linearNV set int primitives; // mesh shader "max_primitives"DerivativeGroupLinear; // true if layout derivative_group_linearNV set + bool layoutPrimitiveCulling; // true if layout primitive_culling set TLayoutDepth getDepth() const { return layoutDepth; } #else TLayoutDepth getDepth() const { return EldNone; } @@ -1252,6 +1269,7 @@ struct TShaderQualifiers { layoutOverrideCoverage = false; layoutDerivativeGroupQuads = false; layoutDerivativeGroupLinear = false; + layoutPrimitiveCulling = false; primitives = TQualifier::layoutNotSet; interlockOrdering = EioNone; #endif @@ -1315,6 +1333,8 @@ struct TShaderQualifiers { primitives = src.primitives; if (src.interlockOrdering != EioNone) interlockOrdering = src.interlockOrdering; + if (src.layoutPrimitiveCulling) + layoutPrimitiveCulling = src.layoutPrimitiveCulling; #endif } }; @@ -1612,6 +1632,23 @@ public: assert(fieldName); return *fieldName; } + TShaderInterface getShaderInterface() const + { + if (basicType != EbtBlock) + return EsiNone; + + switch (qualifier.storage) { + default: + return EsiNone; + case EvqVaryingIn: + return EsiInput; + case EvqVaryingOut: + return EsiOutput; + case EvqUniform: + case EvqBuffer: + return EsiUniform; + } + } virtual TBasicType getBasicType() const { return basicType; } virtual const TSampler& getSampler() const { return sampler; } @@ -1670,7 +1707,7 @@ public: } virtual bool isOpaque() const { return basicType == EbtSampler #ifndef GLSLANG_WEB - || basicType == EbtAtomicUint || basicType == EbtAccStructNV + || basicType == EbtAtomicUint || basicType == EbtAccStruct || basicType == EbtRayQuery #endif ; } virtual bool isBuiltIn() const { return getQualifier().builtIn != EbvNone; } @@ -1946,7 +1983,8 @@ public: case EbtAtomicUint: return "atomic_uint"; case EbtStruct: return "structure"; case EbtBlock: return "block"; - case EbtAccStructNV: return "accelerationStructureNV"; + case EbtAccStruct: return "accelerationStructureNV"; + case EbtRayQuery: return "rayQueryEXT"; case EbtReference: return "reference"; #endif default: return "unknown type"; @@ -2056,7 +2094,7 @@ public: appendStr(" layoutSecondaryViewportRelativeOffset="); appendInt(qualifier.layoutSecondaryViewportRelativeOffset); } - if (qualifier.layoutShaderRecordNV) + if (qualifier.layoutShaderRecord) appendStr(" shaderRecordNV"); appendStr(")"); @@ -2099,6 +2137,8 @@ public: appendStr(" workgroupcoherent"); if (qualifier.subgroupcoherent) appendStr(" subgroupcoherent"); + if (qualifier.shadercallcoherent) + appendStr(" shadercallcoherent"); if (qualifier.nonprivate) appendStr(" nonprivate"); if (qualifier.volatil) diff --git a/src/libraries/glslang/glslang/Include/intermediate.h b/src/libraries/glslang/glslang/Include/intermediate.h index 29d58ca63..30cb6fb17 100644 --- a/src/libraries/glslang/glslang/Include/intermediate.h +++ b/src/libraries/glslang/glslang/Include/intermediate.h @@ -2,6 +2,7 @@ // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2016 LunarG, Inc. // Copyright (C) 2017 ARM Limited. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -621,6 +622,8 @@ enum TOperator { EOpIsHelperInvocation, + EOpDebugPrintf, + // // Branch // @@ -908,12 +911,41 @@ enum TOperator { EOpAverageRounded, EOpMul32x16, - EOpTraceNV, - EOpReportIntersectionNV, - EOpIgnoreIntersectionNV, - EOpTerminateRayNV, - EOpExecuteCallableNV, + EOpTrace, + EOpReportIntersection, + EOpIgnoreIntersection, + EOpTerminateRay, + EOpExecuteCallable, EOpWritePackedPrimitiveIndices4x8NV, + + // + // GL_EXT_ray_query operations + // + + EOpRayQueryInitialize, + EOpRayQueryTerminate, + EOpRayQueryGenerateIntersection, + EOpRayQueryConfirmIntersection, + EOpRayQueryProceed, + EOpRayQueryGetIntersectionType, + EOpRayQueryGetRayTMin, + EOpRayQueryGetRayFlags, + EOpRayQueryGetIntersectionT, + EOpRayQueryGetIntersectionInstanceCustomIndex, + EOpRayQueryGetIntersectionInstanceId, + EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset, + EOpRayQueryGetIntersectionGeometryIndex, + EOpRayQueryGetIntersectionPrimitiveIndex, + EOpRayQueryGetIntersectionBarycentrics, + EOpRayQueryGetIntersectionFrontFace, + EOpRayQueryGetIntersectionCandidateAABBOpaque, + EOpRayQueryGetIntersectionObjectRayDirection, + EOpRayQueryGetIntersectionObjectRayOrigin, + EOpRayQueryGetWorldRayDirection, + EOpRayQueryGetWorldRayOrigin, + EOpRayQueryGetIntersectionObjectToWorld, + EOpRayQueryGetIntersectionWorldToObject, + // // HLSL operations // @@ -1199,6 +1231,7 @@ public: TOperator getFlowOp() const { return flowOp; } TIntermTyped* getExpression() const { return expression; } void setExpression(TIntermTyped* pExpression) { expression = pExpression; } + void updatePrecision(TPrecisionQualifier parentPrecision); protected: TOperator flowOp; TIntermTyped* expression; diff --git a/src/libraries/glslang/glslang/MachineIndependent/Constant.cpp b/src/libraries/glslang/glslang/MachineIndependent/Constant.cpp index 98c2666fb..e21cf427f 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/Constant.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/Constant.cpp @@ -2,7 +2,7 @@ // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2013 LunarG, Inc. // Copyright (C) 2017 ARM Limited. -// Copyright (C) 2018 Google, Inc. +// Copyright (C) 2018-2020 Google, Inc. // // All rights reserved. // @@ -1012,6 +1012,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) case EOpMin: case EOpMax: case EOpMix: + case EOpMod: case EOpClamp: case EOpLessThan: case EOpGreaterThan: @@ -1074,6 +1075,14 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) case EOpPow: newConstArray[comp].setDConst(pow(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst())); break; + case EOpMod: + { + double arg0 = childConstUnions[0][arg0comp].getDConst(); + double arg1 = childConstUnions[1][arg1comp].getDConst(); + double result = arg0 - arg1 * floor(arg0 / arg1); + newConstArray[comp].setDConst(result); + break; + } case EOpMin: switch(children[0]->getAsTyped()->getBasicType()) { case EbtFloat16: diff --git a/src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp b/src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp index b1662abad..3fd6ab21f 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp @@ -1,8 +1,9 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2016 LunarG, Inc. -// Copyright (C) 2015-2018 Google, Inc. +// Copyright (C) 2015-2020 Google, Inc. // Copyright (C) 2017 ARM Limited. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -56,9 +57,9 @@ namespace glslang { // TODO: ARB_Compatability: do full extension support -const bool ARBCompatibility = true; +const bool ARBCompatibility = false; -const bool ForwardCompatibility = false; +const bool ForwardCompatibility = true; // change this back to false if depending on textual spellings of texturing calls when consuming the AST // Using PureOperatorBuiltins=false is deprecated. @@ -125,8 +126,6 @@ enum ArgClass { }; // Mixtures of the above, to help the function tables const ArgClass ClassV1FIOCV = (ArgClass)(ClassV1 | ClassFIO | ClassCV); -const ArgClass ClassV1FOCV = (ArgClass)(ClassV1 | ClassFO | ClassCV); -const ArgClass ClassV1CV = (ArgClass)(ClassV1 | ClassCV); const ArgClass ClassBNS = (ArgClass)(ClassB | ClassNS); const ArgClass ClassRSNS = (ArgClass)(ClassRS | ClassNS); @@ -147,17 +146,21 @@ EProfile EDesktopProfile = static_cast(ENoProfile | ECoreProfile | ECo // Declare pointers to put into the table for versioning. #ifdef GLSLANG_WEB const Versioning* Es300Desktop130 = nullptr; - const Versioning* Es310Desktop430 = nullptr; + const Versioning* Es310Desktop420 = nullptr; +#elif defined(GLSLANG_ANGLE) + const Versioning* Es300Desktop130 = nullptr; + const Versioning* Es310Desktop420 = nullptr; + const Versioning* Es310Desktop450 = nullptr; #else const Versioning Es300Desktop130Version[] = { { EEsProfile, 0, 300, 0, nullptr }, { EDesktopProfile, 0, 130, 0, nullptr }, { EBadProfile } }; const Versioning* Es300Desktop130 = &Es300Desktop130Version[0]; - const Versioning Es310Desktop430Version[] = { { EEsProfile, 0, 310, 0, nullptr }, - { EDesktopProfile, 0, 430, 0, nullptr }, + const Versioning Es310Desktop420Version[] = { { EEsProfile, 0, 310, 0, nullptr }, + { EDesktopProfile, 0, 420, 0, nullptr }, { EBadProfile } }; - const Versioning* Es310Desktop430 = &Es310Desktop430Version[0]; + const Versioning* Es310Desktop420 = &Es310Desktop420Version[0]; const Versioning Es310Desktop450Version[] = { { EEsProfile, 0, 310, 0, nullptr }, { EDesktopProfile, 0, 450, 0, nullptr }, @@ -257,14 +260,14 @@ const BuiltInFunction BaseFunctions[] = { { EOpGreaterThanEqual, "greaterThanEqual", 2, TypeU, ClassBNS, Es300Desktop130 }, { EOpVectorEqual, "equal", 2, TypeU, ClassBNS, Es300Desktop130 }, { EOpVectorNotEqual, "notEqual", 2, TypeU, ClassBNS, Es300Desktop130 }, - { EOpAtomicAdd, "atomicAdd", 2, TypeIU, ClassV1FIOCV, Es310Desktop430 }, - { EOpAtomicMin, "atomicMin", 2, TypeIU, ClassV1FIOCV, Es310Desktop430 }, - { EOpAtomicMax, "atomicMax", 2, TypeIU, ClassV1FIOCV, Es310Desktop430 }, - { EOpAtomicAnd, "atomicAnd", 2, TypeIU, ClassV1FIOCV, Es310Desktop430 }, - { EOpAtomicOr, "atomicOr", 2, TypeIU, ClassV1FIOCV, Es310Desktop430 }, - { EOpAtomicXor, "atomicXor", 2, TypeIU, ClassV1FIOCV, Es310Desktop430 }, - { EOpAtomicExchange, "atomicExchange", 2, TypeIU, ClassV1FIOCV, Es310Desktop430 }, - { EOpAtomicCompSwap, "atomicCompSwap", 3, TypeIU, ClassV1FIOCV, Es310Desktop430 }, + { EOpAtomicAdd, "atomicAdd", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, + { EOpAtomicMin, "atomicMin", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, + { EOpAtomicMax, "atomicMax", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, + { EOpAtomicAnd, "atomicAnd", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, + { EOpAtomicOr, "atomicOr", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, + { EOpAtomicXor, "atomicXor", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, + { EOpAtomicExchange, "atomicExchange", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, + { EOpAtomicCompSwap, "atomicCompSwap", 3, TypeIU, ClassV1FIOCV, Es310Desktop420 }, #ifndef GLSLANG_WEB { EOpMix, "mix", 3, TypeB, ClassRegular, Es310Desktop450 }, { EOpMix, "mix", 3, TypeIU, ClassLB, Es310Desktop450 }, @@ -416,7 +419,7 @@ void AddTabledBuiltin(TString& decls, const BuiltInFunction& function) // See if the tabled versioning information allows the current version. bool ValidVersion(const BuiltInFunction& function, int version, EProfile profile, const SpvVersion& /* spVersion */) { -#ifdef GLSLANG_WEB +#if defined(GLSLANG_WEB) || defined(GLSLANG_ANGLE) // all entries in table are valid return true; #endif @@ -500,7 +503,7 @@ TBuiltIns::TBuiltIns() prefixes[EbtFloat] = ""; prefixes[EbtInt] = "i"; prefixes[EbtUint] = "u"; -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) prefixes[EbtFloat16] = "f16"; prefixes[EbtInt8] = "i8"; prefixes[EbtUint8] = "u8"; @@ -517,7 +520,9 @@ TBuiltIns::TBuiltIns() dimMap[Esd3D] = 3; dimMap[EsdCube] = 3; #ifndef GLSLANG_WEB +#ifndef GLSLANG_ANGLE dimMap[Esd1D] = 1; +#endif dimMap[EsdRect] = 2; dimMap[EsdBuffer] = 1; dimMap[EsdSubpass] = 2; // potentially unused for now @@ -542,6 +547,9 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV #ifdef GLSLANG_WEB version = 310; profile = EEsProfile; +#elif defined(GLSLANG_ANGLE) + version = 450; + profile = ECoreProfile; #endif addTabledBuiltins(version, profile, spvVersion); @@ -587,6 +595,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "vec4 fwidthCoarse(vec4 p);" ); +#ifndef GLSLANG_ANGLE TString derivativesAndControl16bits ( "float16_t dFdx(float16_t);" "f16vec2 dFdx(f16vec2);" @@ -1174,6 +1183,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n" ); } +#endif // !GLSLANG_ANGLE if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 430)) { @@ -1211,6 +1221,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } +#ifndef GLSLANG_ANGLE if (profile != EEsProfile && version >= 440) { commonBuiltins.append( "uint64_t atomicMin(coherent volatile inout uint64_t, uint64_t);" @@ -1242,11 +1253,19 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV " int64_t atomicAdd(coherent volatile inout int64_t, int64_t);" "uint64_t atomicAdd(coherent volatile inout uint64_t, uint64_t, int, int, int);" " int64_t atomicAdd(coherent volatile inout int64_t, int64_t, int, int, int);" + " float atomicAdd(coherent volatile inout float, float);" + " float atomicAdd(coherent volatile inout float, float, int, int, int);" + " double atomicAdd(coherent volatile inout double, double);" + " double atomicAdd(coherent volatile inout double, double, int, int, int);" "uint64_t atomicExchange(coherent volatile inout uint64_t, uint64_t);" " int64_t atomicExchange(coherent volatile inout int64_t, int64_t);" "uint64_t atomicExchange(coherent volatile inout uint64_t, uint64_t, int, int, int);" " int64_t atomicExchange(coherent volatile inout int64_t, int64_t, int, int, int);" + " float atomicExchange(coherent volatile inout float, float);" + " float atomicExchange(coherent volatile inout float, float, int, int, int);" + " double atomicExchange(coherent volatile inout double, double);" + " double atomicExchange(coherent volatile inout double, double, int, int, int);" "uint64_t atomicCompSwap(coherent volatile inout uint64_t, uint64_t, uint64_t);" " int64_t atomicCompSwap(coherent volatile inout int64_t, int64_t, int64_t);" @@ -1255,15 +1274,20 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "uint64_t atomicLoad(coherent volatile in uint64_t, int, int, int);" " int64_t atomicLoad(coherent volatile in int64_t, int, int, int);" + " float atomicLoad(coherent volatile in float, int, int, int);" + " double atomicLoad(coherent volatile in double, int, int, int);" "void atomicStore(coherent volatile out uint64_t, uint64_t, int, int, int);" "void atomicStore(coherent volatile out int64_t, int64_t, int, int, int);" + "void atomicStore(coherent volatile out float, float, int, int, int);" + "void atomicStore(coherent volatile out double, double, int, int, int);" "\n"); } -#endif +#endif // !GLSLANG_ANGLE +#endif // !GLSLANG_WEB if ((profile == EEsProfile && version >= 300) || - (profile != EEsProfile && version >= 330)) { + (profile != EEsProfile && version >= 150)) { // GL_ARB_shader_bit_encoding commonBuiltins.append( "int floatBitsToInt(highp float value);" "ivec2 floatBitsToInt(highp vec2 value);" @@ -1300,6 +1324,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } +#ifndef GLSLANG_ANGLE if (profile != EEsProfile && version >= 150) { // ARB_gpu_shader_fp64 commonBuiltins.append( "double fma(double, double, double);" @@ -1308,6 +1333,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "dvec4 fma(dvec4, dvec4, dvec4 );" "\n"); } +#endif if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 400)) { @@ -1325,6 +1351,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } +#ifndef GLSLANG_ANGLE if (profile != EEsProfile && version >= 150) { // ARB_gpu_shader_fp64 commonBuiltins.append( "double frexp(double, out int);" @@ -1342,10 +1369,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } +#endif #endif if ((profile == EEsProfile && version >= 300) || - (profile != EEsProfile && version >= 400)) { + (profile != EEsProfile && version >= 150)) { commonBuiltins.append( "highp uint packUnorm2x16(vec2);" "vec2 unpackUnorm2x16(highp uint);" @@ -1353,7 +1381,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV } if ((profile == EEsProfile && version >= 300) || - (profile != EEsProfile && version >= 420)) { + (profile != EEsProfile && version >= 150)) { commonBuiltins.append( "highp uint packSnorm2x16(vec2);" " vec2 unpackSnorm2x16(highp uint);" @@ -1365,7 +1393,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV commonBuiltins.append( "mediump vec2 unpackHalf2x16(highp uint);" "\n"); - } else if (profile != EEsProfile && version >= 420) { + } else if (profile != EEsProfile && version >= 150) { commonBuiltins.append( " vec2 unpackHalf2x16(highp uint);" "\n"); @@ -1373,7 +1401,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV #ifndef GLSLANG_WEB if ((profile == EEsProfile && version >= 310) || - (profile != EEsProfile && version >= 400)) { + (profile != EEsProfile && version >= 150)) { commonBuiltins.append( "highp uint packSnorm4x8(vec4);" "highp uint packUnorm4x8(vec4);" @@ -1385,7 +1413,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "mediump vec4 unpackSnorm4x8(highp uint);" "mediump vec4 unpackUnorm4x8(highp uint);" "\n"); - } else if (profile != EEsProfile && version >= 400) { + } else if (profile != EEsProfile && version >= 150) { commonBuiltins.append( "vec4 unpackSnorm4x8(highp uint);" "vec4 unpackUnorm4x8(highp uint);" @@ -1451,6 +1479,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV } #ifndef GLSLANG_WEB +#ifndef GLSLANG_ANGLE // // Original-style texture functions existing in all stages. // (Per-stage functions below.) @@ -1605,6 +1634,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } } +#endif // !GLSLANG_ANGLE // Bitfield if ((profile == EEsProfile && version >= 310) || @@ -1747,6 +1777,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } +#ifndef GLSLANG_ANGLE // GL_ARB_shader_ballot if (profile != EEsProfile && version >= 450) { commonBuiltins.append( @@ -3067,7 +3098,27 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "bool textureFootprintGradClampNV(sampler2D, vec2, vec2, vec2, float, int, bool, out gl_TextureFootprint2DNV);" "\n"); } +#endif // !GLSLANG_ANGLE + if ((profile == EEsProfile && version >= 300 && version < 310) || + (profile != EEsProfile && version >= 150 && version < 450)) { // GL_EXT_shader_integer_mix + commonBuiltins.append("int mix(int, int, bool);" + "ivec2 mix(ivec2, ivec2, bvec2);" + "ivec3 mix(ivec3, ivec3, bvec3);" + "ivec4 mix(ivec4, ivec4, bvec4);" + "uint mix(uint, uint, bool );" + "uvec2 mix(uvec2, uvec2, bvec2);" + "uvec3 mix(uvec3, uvec3, bvec3);" + "uvec4 mix(uvec4, uvec4, bvec4);" + "bool mix(bool, bool, bool );" + "bvec2 mix(bvec2, bvec2, bvec2);" + "bvec3 mix(bvec3, bvec3, bvec3);" + "bvec4 mix(bvec4, bvec4, bvec4);" + + "\n"); + } + +#ifndef GLSLANG_ANGLE // GL_AMD_gpu_shader_half_float/Explicit types if (profile != EEsProfile && version >= 450) { commonBuiltins.append( @@ -3918,28 +3969,30 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "f64vec3 log2(f64vec3);" "f64vec4 log2(f64vec4);" "\n"); - } - if (profile != EEsProfile && version >= 450) { - stageBuiltins[EShLangFragment].append(derivativesAndControl64bits); - stageBuiltins[EShLangFragment].append( - "float64_t interpolateAtCentroid(float64_t);" - "f64vec2 interpolateAtCentroid(f64vec2);" - "f64vec3 interpolateAtCentroid(f64vec3);" - "f64vec4 interpolateAtCentroid(f64vec4);" + } - "float64_t interpolateAtSample(float64_t, int);" - "f64vec2 interpolateAtSample(f64vec2, int);" - "f64vec3 interpolateAtSample(f64vec3, int);" - "f64vec4 interpolateAtSample(f64vec4, int);" + if (profile != EEsProfile && version >= 450) { + stageBuiltins[EShLangFragment].append(derivativesAndControl64bits); + stageBuiltins[EShLangFragment].append( + "float64_t interpolateAtCentroid(float64_t);" + "f64vec2 interpolateAtCentroid(f64vec2);" + "f64vec3 interpolateAtCentroid(f64vec3);" + "f64vec4 interpolateAtCentroid(f64vec4);" - "float64_t interpolateAtOffset(float64_t, f64vec2);" - "f64vec2 interpolateAtOffset(f64vec2, f64vec2);" - "f64vec3 interpolateAtOffset(f64vec3, f64vec2);" - "f64vec4 interpolateAtOffset(f64vec4, f64vec2);" + "float64_t interpolateAtSample(float64_t, int);" + "f64vec2 interpolateAtSample(f64vec2, int);" + "f64vec3 interpolateAtSample(f64vec3, int);" + "f64vec4 interpolateAtSample(f64vec4, int);" - "\n"); + "float64_t interpolateAtOffset(float64_t, f64vec2);" + "f64vec2 interpolateAtOffset(f64vec2, f64vec2);" + "f64vec3 interpolateAtOffset(f64vec3, f64vec2);" + "f64vec4 interpolateAtOffset(f64vec4, f64vec2);" + + "\n"); } +#endif // !GLSLANG_ANGLE //============================================================================ // @@ -3955,6 +4008,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV if (spvVersion.vulkan == 0 && IncludeLegacy(version, profile, spvVersion)) stageBuiltins[EShLangVertex].append("vec4 ftransform();"); +#ifndef GLSLANG_ANGLE // // Original-style texture Functions with lod. // @@ -4020,6 +4074,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } } +#endif // !GLSLANG_ANGLE if ((profile != EEsProfile && version >= 150) || (profile == EEsProfile && version >= 310)) { @@ -4040,7 +4095,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "void EndPrimitive();" "\n"); } -#endif +#endif // !GLSLANG_WEB //============================================================================ // @@ -4079,10 +4134,10 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV } #ifndef GLSLANG_WEB if ((profile != EEsProfile && version >= 420) || esBarrier) { - commonBuiltins.append( - "void memoryBarrierAtomicCounter();" - "void memoryBarrierImage();" - ); + if (spvVersion.vulkan == 0) { + commonBuiltins.append("void memoryBarrierAtomicCounter();"); + } + commonBuiltins.append("void memoryBarrierImage();"); } if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { stageBuiltins[EShLangMeshNV].append( @@ -4098,6 +4153,9 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV commonBuiltins.append("void controlBarrier(int, int, int, int);\n" "void memoryBarrier(int, int, int);\n"); + commonBuiltins.append("void debugPrintfEXT();\n"); + +#ifndef GLSLANG_ANGLE if (profile != EEsProfile && version >= 450) { // coopMatStoreNV perhaps ought to have "out" on the buf parameter, but // adding it introduces undesirable tempArgs on the stack. What we want @@ -4224,6 +4282,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } +#endif // !GLSLANG_ANGLE // GL_ARB_derivative_control if (profile != EEsProfile && version >= 400) { @@ -4261,6 +4320,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "bool helperInvocationEXT();" "\n"); +#ifndef GLSLANG_ANGLE // GL_AMD_shader_explicit_vertex_parameter if (profile != EEsProfile && version >= 450) { stageBuiltins[EShLangFragment].append( @@ -4335,37 +4395,74 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } - // Builtins for GL_NV_ray_tracing + // Builtins for GL_NV_ray_tracing/GL_EXT_ray_tracing/GL_EXT_ray_query if (profile != EEsProfile && version >= 460) { - stageBuiltins[EShLangRayGenNV].append( - "void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" - "void executeCallableNV(uint, int);" + commonBuiltins.append("void rayQueryInitializeEXT(rayQueryEXT, accelerationStructureEXT, uint, uint, vec3, float, vec3, float);" + "void rayQueryTerminateEXT(rayQueryEXT);" + "void rayQueryGenerateIntersectionEXT(rayQueryEXT, float);" + "void rayQueryConfirmIntersectionEXT(rayQueryEXT);" + "bool rayQueryProceedEXT(rayQueryEXT);" + "uint rayQueryGetIntersectionTypeEXT(rayQueryEXT, bool);" + "float rayQueryGetRayTMinEXT(rayQueryEXT);" + "uint rayQueryGetRayFlagsEXT(rayQueryEXT);" + "vec3 rayQueryGetWorldRayOriginEXT(rayQueryEXT);" + "vec3 rayQueryGetWorldRayDirectionEXT(rayQueryEXT);" + "float rayQueryGetIntersectionTEXT(rayQueryEXT, bool);" + "int rayQueryGetIntersectionInstanceCustomIndexEXT(rayQueryEXT, bool);" + "int rayQueryGetIntersectionInstanceIdEXT(rayQueryEXT, bool);" + "uint rayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetEXT(rayQueryEXT, bool);" + "int rayQueryGetIntersectionGeometryIndexEXT(rayQueryEXT, bool);" + "int rayQueryGetIntersectionPrimitiveIndexEXT(rayQueryEXT, bool);" + "vec2 rayQueryGetIntersectionBarycentricsEXT(rayQueryEXT, bool);" + "bool rayQueryGetIntersectionFrontFaceEXT(rayQueryEXT, bool);" + "bool rayQueryGetIntersectionCandidateAABBOpaqueEXT(rayQueryEXT);" + "vec3 rayQueryGetIntersectionObjectRayDirectionEXT(rayQueryEXT, bool);" + "vec3 rayQueryGetIntersectionObjectRayOriginEXT(rayQueryEXT, bool);" + "mat4x3 rayQueryGetIntersectionObjectToWorldEXT(rayQueryEXT, bool);" + "mat4x3 rayQueryGetIntersectionWorldToObjectEXT(rayQueryEXT, bool);" "\n"); - stageBuiltins[EShLangIntersectNV].append( + + stageBuiltins[EShLangRayGen].append( + "void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" + "void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" + "void executeCallableNV(uint, int);" + "void executeCallableEXT(uint, int);" + "\n"); + stageBuiltins[EShLangIntersect].append( "bool reportIntersectionNV(float, uint);" + "bool reportIntersectionEXT(float, uint);" "\n"); - stageBuiltins[EShLangAnyHitNV].append( + stageBuiltins[EShLangAnyHit].append( "void ignoreIntersectionNV();" + "void ignoreIntersectionEXT();" "void terminateRayNV();" + "void terminateRayEXT();" "\n"); - stageBuiltins[EShLangClosestHitNV].append( + stageBuiltins[EShLangClosestHit].append( "void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" + "void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" "void executeCallableNV(uint, int);" + "void executeCallableEXT(uint, int);" "\n"); - stageBuiltins[EShLangMissNV].append( + stageBuiltins[EShLangMiss].append( "void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" + "void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" "void executeCallableNV(uint, int);" + "void executeCallableEXT(uint, int);" "\n"); - stageBuiltins[EShLangCallableNV].append( + stageBuiltins[EShLangCallable].append( "void executeCallableNV(uint, int);" + "void executeCallableEXT(uint, int);" "\n"); } +#endif // !GLSLANG_ANGLE //E_SPV_NV_compute_shader_derivatives if ((profile == EEsProfile && version >= 320) || (profile != EEsProfile && version >= 450)) { stageBuiltins[EShLangCompute].append(derivativeControls); stageBuiltins[EShLangCompute].append("\n"); } +#ifndef GLSLANG_ANGLE if (profile != EEsProfile && version >= 450) { stageBuiltins[EShLangCompute].append(derivativesAndControl16bits); stageBuiltins[EShLangCompute].append(derivativesAndControl64bits); @@ -4378,7 +4475,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "void writePackedPrimitiveIndices4x8NV(uint, uint);" "\n"); } -#endif +#endif // !GLSLANG_ANGLE +#endif // !GLSLANG_WEB //============================================================================ // @@ -4415,7 +4513,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) if (spvVersion.spv == 0 && IncludeLegacy(version, profile, spvVersion)) { // // Matrix state. p. 31, 32, 37, 39, 40. @@ -4533,7 +4631,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#endif +#endif // !GLSLANG_WEB && !GLSLANG_ANGLE //============================================================================ // @@ -4564,6 +4662,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV } #ifndef GLSLANG_WEB +#ifndef GLSLANG_ANGLE //============================================================================ // // Define the interface to the mesh/task shader. @@ -4651,6 +4750,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } } +#endif // !GLSLANG_ANGLE //============================================================================ // @@ -5321,6 +5421,15 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV #ifndef GLSLANG_WEB + if ((profile != EEsProfile && version >= 140) || + (profile == EEsProfile && version >= 310)) { + stageBuiltins[EShLangFragment].append( + "flat in highp int gl_DeviceIndex;" // GL_EXT_device_group + "flat in highp int gl_ViewIndex;" // GL_EXT_multiview + "\n"); + } + +#ifndef GLSLANG_ANGLE // GL_ARB_shader_ballot if (profile != EEsProfile && version >= 450) { const char* ballotDecls = @@ -5351,14 +5460,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV stageBuiltins[EShLangTaskNV] .append(ballotDecls); } - if ((profile != EEsProfile && version >= 140) || - (profile == EEsProfile && version >= 310)) { - stageBuiltins[EShLangFragment].append( - "flat in highp int gl_DeviceIndex;" // GL_EXT_device_group - "flat in highp int gl_ViewIndex;" // GL_EXT_multiview - "\n"); - } - // GL_KHR_shader_subgroup if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 140)) { @@ -5406,118 +5507,173 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV stageBuiltins[EShLangMeshNV] .append(computeSubgroupDecls); stageBuiltins[EShLangTaskNV] .append(subgroupDecls); stageBuiltins[EShLangTaskNV] .append(computeSubgroupDecls); - stageBuiltins[EShLangRayGenNV] .append(subgroupDecls); - stageBuiltins[EShLangIntersectNV] .append(subgroupDecls); - stageBuiltins[EShLangAnyHitNV] .append(subgroupDecls); - stageBuiltins[EShLangClosestHitNV] .append(subgroupDecls); - stageBuiltins[EShLangMissNV] .append(subgroupDecls); - stageBuiltins[EShLangCallableNV] .append(subgroupDecls); + stageBuiltins[EShLangRayGen] .append(subgroupDecls); + stageBuiltins[EShLangIntersect] .append(subgroupDecls); + stageBuiltins[EShLangAnyHit] .append(subgroupDecls); + stageBuiltins[EShLangClosestHit] .append(subgroupDecls); + stageBuiltins[EShLangMiss] .append(subgroupDecls); + stageBuiltins[EShLangCallable] .append(subgroupDecls); } - // GL_NV_ray_tracing + // GL_NV_ray_tracing/GL_EXT_ray_tracing if (profile != EEsProfile && version >= 460) { const char *constRayFlags = "const uint gl_RayFlagsNoneNV = 0U;" + "const uint gl_RayFlagsNoneEXT = 0U;" "const uint gl_RayFlagsOpaqueNV = 1U;" + "const uint gl_RayFlagsOpaqueEXT = 1U;" "const uint gl_RayFlagsNoOpaqueNV = 2U;" + "const uint gl_RayFlagsNoOpaqueEXT = 2U;" "const uint gl_RayFlagsTerminateOnFirstHitNV = 4U;" + "const uint gl_RayFlagsTerminateOnFirstHitEXT = 4U;" "const uint gl_RayFlagsSkipClosestHitShaderNV = 8U;" + "const uint gl_RayFlagsSkipClosestHitShaderEXT = 8U;" "const uint gl_RayFlagsCullBackFacingTrianglesNV = 16U;" + "const uint gl_RayFlagsCullBackFacingTrianglesEXT = 16U;" "const uint gl_RayFlagsCullFrontFacingTrianglesNV = 32U;" + "const uint gl_RayFlagsCullFrontFacingTrianglesEXT = 32U;" "const uint gl_RayFlagsCullOpaqueNV = 64U;" + "const uint gl_RayFlagsCullOpaqueEXT = 64U;" "const uint gl_RayFlagsCullNoOpaqueNV = 128U;" + "const uint gl_RayFlagsCullNoOpaqueEXT = 128U;" + "const uint gl_RayFlagsSkipTrianglesEXT = 256U;" + "const uint gl_RayFlagsSkipAABBEXT = 512U;" + "const uint gl_HitKindFrontFacingTriangleEXT = 254U;" + "const uint gl_HitKindBackFacingTriangleEXT = 255U;" "\n"; + + const char *constRayQueryIntersection = + "const uint gl_RayQueryCandidateIntersectionEXT = 0U;" + "const uint gl_RayQueryCommittedIntersectionEXT = 1U;" + "const uint gl_RayQueryCommittedIntersectionNoneEXT = 0U;" + "const uint gl_RayQueryCommittedIntersectionTriangleEXT = 1U;" + "const uint gl_RayQueryCommittedIntersectionGeneratedEXT = 2U;" + "const uint gl_RayQueryCandidateIntersectionTriangleEXT = 0U;" + "const uint gl_RayQueryCandidateIntersectionAABBEXT = 1U;" + "\n"; + const char *rayGenDecls = "in uvec3 gl_LaunchIDNV;" + "in uvec3 gl_LaunchIDEXT;" "in uvec3 gl_LaunchSizeNV;" + "in uvec3 gl_LaunchSizeEXT;" "\n"; const char *intersectDecls = "in uvec3 gl_LaunchIDNV;" + "in uvec3 gl_LaunchIDEXT;" "in uvec3 gl_LaunchSizeNV;" + "in uvec3 gl_LaunchSizeEXT;" "in int gl_PrimitiveID;" "in int gl_InstanceID;" "in int gl_InstanceCustomIndexNV;" + "in int gl_InstanceCustomIndexEXT;" + "in int gl_GeometryIndexEXT;" "in vec3 gl_WorldRayOriginNV;" + "in vec3 gl_WorldRayOriginEXT;" "in vec3 gl_WorldRayDirectionNV;" + "in vec3 gl_WorldRayDirectionEXT;" "in vec3 gl_ObjectRayOriginNV;" + "in vec3 gl_ObjectRayOriginEXT;" "in vec3 gl_ObjectRayDirectionNV;" + "in vec3 gl_ObjectRayDirectionEXT;" "in float gl_RayTminNV;" + "in float gl_RayTminEXT;" "in float gl_RayTmaxNV;" + "in float gl_RayTmaxEXT;" "in mat4x3 gl_ObjectToWorldNV;" + "in mat4x3 gl_ObjectToWorldEXT;" + "in mat3x4 gl_ObjectToWorld3x4EXT;" "in mat4x3 gl_WorldToObjectNV;" + "in mat4x3 gl_WorldToObjectEXT;" + "in mat3x4 gl_WorldToObject3x4EXT;" "in uint gl_IncomingRayFlagsNV;" + "in uint gl_IncomingRayFlagsEXT;" "\n"; const char *hitDecls = "in uvec3 gl_LaunchIDNV;" + "in uvec3 gl_LaunchIDEXT;" "in uvec3 gl_LaunchSizeNV;" + "in uvec3 gl_LaunchSizeEXT;" "in int gl_PrimitiveID;" "in int gl_InstanceID;" "in int gl_InstanceCustomIndexNV;" + "in int gl_InstanceCustomIndexEXT;" + "in int gl_GeometryIndexEXT;" "in vec3 gl_WorldRayOriginNV;" + "in vec3 gl_WorldRayOriginEXT;" "in vec3 gl_WorldRayDirectionNV;" + "in vec3 gl_WorldRayDirectionEXT;" "in vec3 gl_ObjectRayOriginNV;" + "in vec3 gl_ObjectRayOriginEXT;" "in vec3 gl_ObjectRayDirectionNV;" + "in vec3 gl_ObjectRayDirectionEXT;" "in float gl_RayTminNV;" + "in float gl_RayTminEXT;" "in float gl_RayTmaxNV;" + "in float gl_RayTmaxEXT;" "in float gl_HitTNV;" + "in float gl_HitTEXT;" "in uint gl_HitKindNV;" + "in uint gl_HitKindEXT;" "in mat4x3 gl_ObjectToWorldNV;" + "in mat4x3 gl_ObjectToWorldEXT;" + "in mat3x4 gl_ObjectToWorld3x4EXT;" "in mat4x3 gl_WorldToObjectNV;" + "in mat4x3 gl_WorldToObjectEXT;" + "in mat3x4 gl_WorldToObject3x4EXT;" "in uint gl_IncomingRayFlagsNV;" + "in uint gl_IncomingRayFlagsEXT;" "\n"; const char *missDecls = "in uvec3 gl_LaunchIDNV;" + "in uvec3 gl_LaunchIDEXT;" "in uvec3 gl_LaunchSizeNV;" + "in uvec3 gl_LaunchSizeEXT;" "in vec3 gl_WorldRayOriginNV;" + "in vec3 gl_WorldRayOriginEXT;" "in vec3 gl_WorldRayDirectionNV;" + "in vec3 gl_WorldRayDirectionEXT;" "in vec3 gl_ObjectRayOriginNV;" "in vec3 gl_ObjectRayDirectionNV;" "in float gl_RayTminNV;" + "in float gl_RayTminEXT;" "in float gl_RayTmaxNV;" + "in float gl_RayTmaxEXT;" "in uint gl_IncomingRayFlagsNV;" + "in uint gl_IncomingRayFlagsEXT;" "\n"; const char *callableDecls = "in uvec3 gl_LaunchIDNV;" + "in uvec3 gl_LaunchIDEXT;" "in uvec3 gl_LaunchSizeNV;" + "in uvec3 gl_LaunchSizeEXT;" "\n"; - stageBuiltins[EShLangRayGenNV].append(rayGenDecls); - stageBuiltins[EShLangRayGenNV].append(constRayFlags); - stageBuiltins[EShLangIntersectNV].append(intersectDecls); - stageBuiltins[EShLangIntersectNV].append(constRayFlags); + commonBuiltins.append(constRayQueryIntersection); + commonBuiltins.append(constRayFlags); - stageBuiltins[EShLangAnyHitNV].append(hitDecls); - stageBuiltins[EShLangAnyHitNV].append(constRayFlags); - - stageBuiltins[EShLangClosestHitNV].append(hitDecls); - stageBuiltins[EShLangClosestHitNV].append(constRayFlags); - - stageBuiltins[EShLangMissNV].append(missDecls); - stageBuiltins[EShLangMissNV].append(constRayFlags); - - stageBuiltins[EShLangCallableNV].append(callableDecls); - stageBuiltins[EShLangCallableNV].append(constRayFlags); + stageBuiltins[EShLangRayGen].append(rayGenDecls); + stageBuiltins[EShLangIntersect].append(intersectDecls); + stageBuiltins[EShLangAnyHit].append(hitDecls); + stageBuiltins[EShLangClosestHit].append(hitDecls); + stageBuiltins[EShLangMiss].append(missDecls); + stageBuiltins[EShLangCallable].append(callableDecls); } + if ((profile != EEsProfile && version >= 140)) { const char *deviceIndex = "in highp int gl_DeviceIndex;" // GL_EXT_device_group "\n"; - stageBuiltins[EShLangRayGenNV].append(deviceIndex); - stageBuiltins[EShLangIntersectNV].append(deviceIndex); - stageBuiltins[EShLangAnyHitNV].append(deviceIndex); - stageBuiltins[EShLangClosestHitNV].append(deviceIndex); - stageBuiltins[EShLangMissNV].append(deviceIndex); - } - - if (version >= 300 /* both ES and non-ES */) { - stageBuiltins[EShLangFragment].append( - "flat in highp uint gl_ViewID_OVR;" // GL_OVR_multiview, GL_OVR_multiview2 - "\n"); + stageBuiltins[EShLangRayGen].append(deviceIndex); + stageBuiltins[EShLangIntersect].append(deviceIndex); + stageBuiltins[EShLangAnyHit].append(deviceIndex); + stageBuiltins[EShLangClosestHit].append(deviceIndex); + stageBuiltins[EShLangMiss].append(deviceIndex); } if ((profile != EEsProfile && version >= 420) || @@ -5527,6 +5683,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV commonBuiltins.append("const int gl_ScopeSubgroup = 3;\n"); commonBuiltins.append("const int gl_ScopeInvocation = 4;\n"); commonBuiltins.append("const int gl_ScopeQueueFamily = 5;\n"); + commonBuiltins.append("const int gl_ScopeShaderCallEXT = 6;\n"); commonBuiltins.append("const int gl_SemanticsRelaxed = 0x0;\n"); commonBuiltins.append("const int gl_SemanticsAcquire = 0x2;\n"); @@ -5542,7 +5699,15 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV commonBuiltins.append("const int gl_StorageSemanticsImage = 0x800;\n"); commonBuiltins.append("const int gl_StorageSemanticsOutput = 0x1000;\n"); } -#endif + +#endif // !GLSLANG_ANGLE + + if (version >= 300 /* both ES and non-ES */) { + stageBuiltins[EShLangFragment].append( + "flat in highp uint gl_ViewID_OVR;" // GL_OVR_multiview, GL_OVR_multiview2 + "\n"); + } +#endif // !GLSLANG_WEB // printf("%s\n", commonBuiltins.c_str()); // printf("%s\n", stageBuiltins[EShLangFragment].c_str()); @@ -5560,13 +5725,16 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c // // enumerate all the types + const TBasicType bTypes[] = { EbtFloat, EbtInt, EbtUint, +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + EbtFloat16 +#endif + }; #ifdef GLSLANG_WEB - const TBasicType bTypes[] = { EbtFloat, EbtInt, EbtUint }; bool skipBuffer = true; bool skipCubeArrayed = true; const int image = 0; #else - const TBasicType bTypes[] = { EbtFloat, EbtInt, EbtUint, EbtFloat16 }; bool skipBuffer = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 140); bool skipCubeArrayed = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 130); for (int image = 0; image <= 1; ++image) // loop over "bool" image vs sampler @@ -5591,8 +5759,12 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c for (int arrayed = 0; arrayed <= 1; ++arrayed) { // loop over "bool" arrayed or not #ifdef GLSLANG_WEB for (int dim = Esd2D; dim <= EsdCube; ++dim) { // 2D, 3D, and Cube +#else +#if defined(GLSLANG_ANGLE) + for (int dim = Esd2D; dim < EsdNumDims; ++dim) { // 2D, ..., buffer, subpass #else for (int dim = Esd1D; dim < EsdNumDims; ++dim) { // 1D, ..., buffer, subpass +#endif if (dim == EsdSubpass && spvVersion.vulkan == 0) continue; if (dim == EsdSubpass && (image || shadow || arrayed)) @@ -5723,7 +5895,7 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int return; #endif - if (sampler.isImage() && ((profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 430))) + if (sampler.isImage() && ((profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 420))) return; if (profile == EEsProfile) @@ -5762,9 +5934,9 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int // // textureQueryLod(), fragment stage only - // + // Also enabled with extension GL_ARB_texture_query_lod - if (profile != EEsProfile && version >= 400 && sampler.isCombined() && sampler.dim != EsdRect && + if (profile != EEsProfile && version >= 150 && sampler.isCombined() && sampler.dim != EsdRect && ! sampler.isMultiSample() && ! sampler.isBuffer()) { for (int f16TexAddr = 0; f16TexAddr < 2; ++f16TexAddr) { if (f16TexAddr && sampler.type != EbtFloat16) @@ -5913,12 +6085,39 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int // not int or uint // GL_ARB_ES3_1_compatibility // TODO: spec issue: are there restrictions on the kind of layout() that can be used? what about dropping memory qualifiers? - if ((profile != EEsProfile && version >= 450) || - (profile == EEsProfile && version >= 310)) { + if (profile == EEsProfile && version >= 310) { commonBuiltins.append("float imageAtomicExchange(volatile coherent "); commonBuiltins.append(imageParams); commonBuiltins.append(", float);\n"); } + if (profile != EEsProfile && version >= 450) { + commonBuiltins.append("float imageAtomicAdd(volatile coherent "); + commonBuiltins.append(imageParams); + commonBuiltins.append(", float);\n"); + + commonBuiltins.append("float imageAtomicAdd(volatile coherent "); + commonBuiltins.append(imageParams); + commonBuiltins.append(", float"); + commonBuiltins.append(", int, int, int);\n"); + + commonBuiltins.append("float imageAtomicExchange(volatile coherent "); + commonBuiltins.append(imageParams); + commonBuiltins.append(", float);\n"); + + commonBuiltins.append("float imageAtomicExchange(volatile coherent "); + commonBuiltins.append(imageParams); + commonBuiltins.append(", float"); + commonBuiltins.append(", int, int, int);\n"); + + commonBuiltins.append("float imageAtomicLoad(readonly volatile coherent "); + commonBuiltins.append(imageParams); + commonBuiltins.append(", int, int, int);\n"); + + commonBuiltins.append("void imageAtomicStore(writeonly volatile coherent "); + commonBuiltins.append(imageParams); + commonBuiltins.append(", float"); + commonBuiltins.append(", int, int, int);\n"); + } } } @@ -5986,6 +6185,9 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, #ifdef GLSLANG_WEB profile = EEsProfile; version = 310; +#elif defined(GLSLANG_ANGLE) + profile = ECoreProfile; + version = 450; #endif // @@ -6062,7 +6264,7 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, continue; // loop over 16-bit floating-point texel addressing -#ifdef GLSLANG_WEB +#if defined(GLSLANG_WEB) || defined(GLSLANG_ANGLE) const int f16TexAddr = 0; #else for (int f16TexAddr = 0; f16TexAddr <= 1; ++f16TexAddr) @@ -6075,7 +6277,7 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, totalDims--; } // loop over "bool" lod clamp -#ifdef GLSLANG_WEB +#if defined(GLSLANG_WEB) || defined(GLSLANG_ANGLE) const int lodClamp = 0; #else for (int lodClamp = 0; lodClamp <= 1 ;++lodClamp) @@ -6087,7 +6289,7 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, continue; // loop over "bool" sparse or not -#ifdef GLSLANG_WEB +#if defined(GLSLANG_WEB) || defined(GLSLANG_ANGLE) const int sparse = 0; #else for (int sparse = 0; sparse <= 1; ++sparse) @@ -6142,7 +6344,7 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, s.append("Offset"); if (lodClamp) s.append("Clamp"); - if (lodClamp || sparse) + if (lodClamp != 0 || sparse) s.append("ARB"); s.append("("); @@ -6242,7 +6444,7 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, s.append(");\n"); // Add to the per-language set of built-ins - if (bias || lodClamp) { + if (bias || lodClamp != 0) { stageBuiltins[EShLangFragment].append(s); stageBuiltins[EShLangCompute].append(s); } else @@ -6271,6 +6473,9 @@ void TBuiltIns::addGatherFunctions(TSampler sampler, const TString& typeName, in #ifdef GLSLANG_WEB profile = EEsProfile; version = 310; +#elif defined(GLSLANG_ANGLE) + profile = ECoreProfile; + version = 450; #endif switch (sampler.dim) { @@ -6514,6 +6719,9 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf #ifdef GLSLANG_WEB version = 310; profile = EEsProfile; +#elif defined(GLSLANG_ANGLE) + version = 450; + profile = ECoreProfile; #endif // @@ -6639,6 +6847,35 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf } } + if (version >= 320) { + // tessellation + + snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlImageUniforms = %d;", resources.maxTessControlImageUniforms); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationImageUniforms = %d;", resources.maxTessEvaluationImageUniforms); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlAtomicCounters = %d;", resources.maxTessControlAtomicCounters); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationAtomicCounters = %d;", resources.maxTessEvaluationAtomicCounters); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlAtomicCounterBuffers = %d;", resources.maxTessControlAtomicCounterBuffers); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationAtomicCounterBuffers = %d;", resources.maxTessEvaluationAtomicCounterBuffers); + s.append(builtInConstant); + } + + if (version >= 100) { + // GL_EXT_blend_func_extended + snprintf(builtInConstant, maxSize, "const mediump int gl_MaxDualSourceDrawBuffersEXT = %d;", resources.maxDualSourceDrawBuffersEXT); + s.append(builtInConstant); + // this is here instead of with the others in initialize(version, profile) due to the dependence on gl_MaxDualSourceDrawBuffersEXT + if (language == EShLangFragment) { + s.append( + "mediump vec4 gl_SecondaryFragColorEXT;" + "mediump vec4 gl_SecondaryFragDataEXT[gl_MaxDualSourceDrawBuffersEXT];" + "\n"); + } + } } else { // non-ES profile @@ -6913,6 +7150,7 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf s.append("\n"); } +#ifndef GLSLANG_ANGLE // atomic counters (some in compute below) if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 420)) { @@ -6949,6 +7187,7 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf s.append("\n"); } +#endif // !GLSLANG_ANGLE // GL_ARB_cull_distance if (profile != EEsProfile && version >= 450) { @@ -6965,6 +7204,7 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf s.append(builtInConstant); } +#ifndef GLSLANG_ANGLE // SPV_NV_mesh_shader if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { snprintf(builtInConstant, maxSize, "const int gl_MaxMeshOutputVerticesNV = %d;", resources.maxMeshOutputVerticesNV); @@ -6987,6 +7227,7 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf s.append("\n"); } +#endif #endif s.append("\n"); @@ -7071,6 +7312,9 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion #ifdef GLSLANG_WEB version = 310; profile = EEsProfile; +#elif defined(GLSLANG_ANGLE) + version = 450; + profile = ECoreProfile; #endif // @@ -7260,7 +7504,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion case EShLangTessEvaluation: case EShLangGeometry: -#endif +#endif // !GLSLANG_WEB SpecialQualifier("gl_Position", EvqPosition, EbvPosition, symbolTable); SpecialQualifier("gl_PointSize", EvqPointSize, EbvPointSize, symbolTable); @@ -7421,7 +7665,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_WarpIDNV", EbvWarpID, symbolTable); BuiltInVariable("gl_SMIDNV", EbvSMID, symbolTable); } -#endif +#endif // !GLSLANG_WEB break; case EShLangFragment: @@ -7451,6 +7695,38 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_FragStencilRefARB", EbvFragStencilRef, symbolTable); } + if (profile != EEsProfile && version < 400) { + symbolTable.setFunctionExtensions("textureQueryLod", 1, &E_GL_ARB_texture_query_lod); + } + + if (profile != EEsProfile && version >= 460) { + symbolTable.setFunctionExtensions("rayQueryInitializeEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryTerminateEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGenerateIntersectionEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryConfirmIntersectionEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryProceedEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionTypeEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionTEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetRayFlagsEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetRayTMinEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionInstanceCustomIndexEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionInstanceIdEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionGeometryIndexEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionPrimitiveIndexEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionBarycentricsEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionFrontFaceEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionCandidateAABBOpaqueEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionObjectRayDirectionEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionObjectRayOriginEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionObjectToWorldEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionWorldToObjectEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetWorldRayOriginEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetWorldRayDirectionEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setVariableExtensions("gl_RayFlagsSkipAABBEXT", 1, &E_GL_EXT_ray_flags_primitive_culling); + symbolTable.setVariableExtensions("gl_RayFlagsSkipTrianglesEXT", 1, &E_GL_EXT_ray_flags_primitive_culling); + } + if ((profile != EEsProfile && version >= 130) || (profile == EEsProfile && version >= 310)) { BuiltInVariable("gl_SampleID", EbvSampleId, symbolTable); @@ -7710,6 +7986,45 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("imageAtomicCompSwap", 1, &E_GL_OES_shader_image_atomic); } + if (profile != EEsProfile && version < 330 ) { + symbolTable.setFunctionExtensions("floatBitsToInt", 1, &E_GL_ARB_shader_bit_encoding); + symbolTable.setFunctionExtensions("floatBitsToUint", 1, &E_GL_ARB_shader_bit_encoding); + symbolTable.setFunctionExtensions("intBitsToFloat", 1, &E_GL_ARB_shader_bit_encoding); + symbolTable.setFunctionExtensions("uintBitsToFloat", 1, &E_GL_ARB_shader_bit_encoding); + } + + if (profile != EEsProfile && version < 430 ) { + symbolTable.setFunctionExtensions("imageSize", 1, &E_GL_ARB_shader_image_size); + } + + // GL_ARB_shader_storage_buffer_object + if (profile != EEsProfile && version < 430 ) { + symbolTable.setFunctionExtensions("atomicAdd", 1, &E_GL_ARB_shader_storage_buffer_object); + symbolTable.setFunctionExtensions("atomicMin", 1, &E_GL_ARB_shader_storage_buffer_object); + symbolTable.setFunctionExtensions("atomicMax", 1, &E_GL_ARB_shader_storage_buffer_object); + symbolTable.setFunctionExtensions("atomicAnd", 1, &E_GL_ARB_shader_storage_buffer_object); + symbolTable.setFunctionExtensions("atomicOr", 1, &E_GL_ARB_shader_storage_buffer_object); + symbolTable.setFunctionExtensions("atomicXor", 1, &E_GL_ARB_shader_storage_buffer_object); + symbolTable.setFunctionExtensions("atomicExchange", 1, &E_GL_ARB_shader_storage_buffer_object); + symbolTable.setFunctionExtensions("atomicCompSwap", 1, &E_GL_ARB_shader_storage_buffer_object); + } + + // GL_ARB_shading_language_packing + if (profile != EEsProfile && version < 400 ) { + symbolTable.setFunctionExtensions("packUnorm2x16", 1, &E_GL_ARB_shading_language_packing); + symbolTable.setFunctionExtensions("unpackUnorm2x16", 1, &E_GL_ARB_shading_language_packing); + symbolTable.setFunctionExtensions("packSnorm4x8", 1, &E_GL_ARB_shading_language_packing); + symbolTable.setFunctionExtensions("packUnorm4x8", 1, &E_GL_ARB_shading_language_packing); + symbolTable.setFunctionExtensions("unpackSnorm4x8", 1, &E_GL_ARB_shading_language_packing); + symbolTable.setFunctionExtensions("unpackUnorm4x8", 1, &E_GL_ARB_shading_language_packing); + } + if (profile != EEsProfile && version < 420 ) { + symbolTable.setFunctionExtensions("packSnorm2x16", 1, &E_GL_ARB_shading_language_packing); + symbolTable.setFunctionExtensions("unpackSnorm2x16", 1, &E_GL_ARB_shading_language_packing); + symbolTable.setFunctionExtensions("unpackHalf2x16", 1, &E_GL_ARB_shading_language_packing); + symbolTable.setFunctionExtensions("packHalf2x16", 1, &E_GL_ARB_shading_language_packing); + } + symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group); BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable); symbolTable.setVariableExtensions("gl_ViewIndex", 1, &E_GL_EXT_multiview); @@ -7877,7 +8192,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion } symbolTable.setFunctionExtensions("helperInvocationEXT", 1, &E_GL_EXT_demote_to_helper_invocation); -#endif +#endif // !GLSLANG_WEB break; case EShLangCompute: @@ -7921,7 +8236,9 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("groupMemoryBarrier", 1, &E_GL_ARB_compute_shader); } + symbolTable.setFunctionExtensions("controlBarrier", 1, &E_GL_KHR_memory_scope_semantics); + symbolTable.setFunctionExtensions("debugPrintfEXT", 1, &E_GL_EXT_debug_printf); // GL_ARB_shader_ballot if (profile != EEsProfile) { @@ -8007,53 +8324,101 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("dFdyCoarse", 1, &E_GL_NV_compute_shader_derivatives); symbolTable.setFunctionExtensions("fwidthCoarse", 1, &E_GL_NV_compute_shader_derivatives); } -#endif +#endif // !GLSLANG_WEB break; -#ifndef GLSLANG_WEB - case EShLangRayGenNV: - case EShLangIntersectNV: - case EShLangAnyHitNV: - case EShLangClosestHitNV: - case EShLangMissNV: - case EShLangCallableNV: +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + case EShLangRayGen: + case EShLangIntersect: + case EShLangAnyHit: + case EShLangClosestHit: + case EShLangMiss: + case EShLangCallable: if (profile != EEsProfile && version >= 460) { + const char *rtexts[] = { E_GL_NV_ray_tracing, E_GL_EXT_ray_tracing }; symbolTable.setVariableExtensions("gl_LaunchIDNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_LaunchIDEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_LaunchSizeNV", 1, &E_GL_NV_ray_tracing); - symbolTable.setVariableExtensions("gl_PrimitiveID", 1, &E_GL_NV_ray_tracing); - symbolTable.setVariableExtensions("gl_InstanceID", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_LaunchSizeEXT", 1, &E_GL_EXT_ray_tracing); + symbolTable.setVariableExtensions("gl_PrimitiveID", 2, rtexts); + symbolTable.setVariableExtensions("gl_InstanceID", 2, rtexts); symbolTable.setVariableExtensions("gl_InstanceCustomIndexNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_InstanceCustomIndexEXT", 1, &E_GL_EXT_ray_tracing); + symbolTable.setVariableExtensions("gl_GeometryIndexEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_WorldRayOriginNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_WorldRayOriginEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_WorldRayDirectionNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_WorldRayDirectionEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_ObjectRayOriginNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_ObjectRayOriginEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_ObjectRayDirectionNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_ObjectRayDirectionEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_RayTminNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_RayTminEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_RayTmaxNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_RayTmaxEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_HitTNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_HitTEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_HitKindNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_HitKindEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_ObjectToWorldNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_ObjectToWorldEXT", 1, &E_GL_EXT_ray_tracing); + symbolTable.setVariableExtensions("gl_ObjectToWorld3x4EXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_WorldToObjectNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_WorldToObjectEXT", 1, &E_GL_EXT_ray_tracing); + symbolTable.setVariableExtensions("gl_WorldToObject3x4EXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_IncomingRayFlagsNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_IncomingRayFlagsEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group); - BuiltInVariable("gl_LaunchIDNV", EbvLaunchIdNV, symbolTable); - BuiltInVariable("gl_LaunchSizeNV", EbvLaunchSizeNV, symbolTable); - BuiltInVariable("gl_PrimitiveID", EbvPrimitiveId, symbolTable); - BuiltInVariable("gl_InstanceID", EbvInstanceId, symbolTable); - BuiltInVariable("gl_InstanceCustomIndexNV", EbvInstanceCustomIndexNV,symbolTable); - BuiltInVariable("gl_WorldRayOriginNV", EbvWorldRayOriginNV, symbolTable); - BuiltInVariable("gl_WorldRayDirectionNV", EbvWorldRayDirectionNV, symbolTable); - BuiltInVariable("gl_ObjectRayOriginNV", EbvObjectRayOriginNV, symbolTable); - BuiltInVariable("gl_ObjectRayDirectionNV", EbvObjectRayDirectionNV, symbolTable); - BuiltInVariable("gl_RayTminNV", EbvRayTminNV, symbolTable); - BuiltInVariable("gl_RayTmaxNV", EbvRayTmaxNV, symbolTable); - BuiltInVariable("gl_HitTNV", EbvHitTNV, symbolTable); - BuiltInVariable("gl_HitKindNV", EbvHitKindNV, symbolTable); - BuiltInVariable("gl_ObjectToWorldNV", EbvObjectToWorldNV, symbolTable); - BuiltInVariable("gl_WorldToObjectNV", EbvWorldToObjectNV, symbolTable); - BuiltInVariable("gl_IncomingRayFlagsNV", EbvIncomingRayFlagsNV, symbolTable); - BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable); + + symbolTable.setFunctionExtensions("traceNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setFunctionExtensions("traceRayEXT", 1, &E_GL_EXT_ray_tracing); + symbolTable.setFunctionExtensions("reportIntersectionNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setFunctionExtensions("reportIntersectionEXT", 1, &E_GL_EXT_ray_tracing); + symbolTable.setFunctionExtensions("ignoreIntersectionNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setFunctionExtensions("ignoreIntersectionEXT", 1, &E_GL_EXT_ray_tracing); + symbolTable.setFunctionExtensions("terminateRayNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setFunctionExtensions("terminateRayEXT", 1, &E_GL_EXT_ray_tracing); + symbolTable.setFunctionExtensions("executeCallableNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setFunctionExtensions("executeCallableEXT", 1, &E_GL_EXT_ray_tracing); + + + BuiltInVariable("gl_LaunchIDNV", EbvLaunchId, symbolTable); + BuiltInVariable("gl_LaunchIDEXT", EbvLaunchId, symbolTable); + BuiltInVariable("gl_LaunchSizeNV", EbvLaunchSize, symbolTable); + BuiltInVariable("gl_LaunchSizeEXT", EbvLaunchSize, symbolTable); + BuiltInVariable("gl_PrimitiveID", EbvPrimitiveId, symbolTable); + BuiltInVariable("gl_InstanceID", EbvInstanceId, symbolTable); + BuiltInVariable("gl_InstanceCustomIndexNV", EbvInstanceCustomIndex,symbolTable); + BuiltInVariable("gl_InstanceCustomIndexEXT", EbvInstanceCustomIndex,symbolTable); + BuiltInVariable("gl_GeometryIndexEXT", EbvGeometryIndex, symbolTable); + BuiltInVariable("gl_WorldRayOriginNV", EbvWorldRayOrigin, symbolTable); + BuiltInVariable("gl_WorldRayOriginEXT", EbvWorldRayOrigin, symbolTable); + BuiltInVariable("gl_WorldRayDirectionNV", EbvWorldRayDirection, symbolTable); + BuiltInVariable("gl_WorldRayDirectionEXT", EbvWorldRayDirection, symbolTable); + BuiltInVariable("gl_ObjectRayOriginNV", EbvObjectRayOrigin, symbolTable); + BuiltInVariable("gl_ObjectRayOriginEXT", EbvObjectRayOrigin, symbolTable); + BuiltInVariable("gl_ObjectRayDirectionNV", EbvObjectRayDirection, symbolTable); + BuiltInVariable("gl_ObjectRayDirectionEXT", EbvObjectRayDirection, symbolTable); + BuiltInVariable("gl_RayTminNV", EbvRayTmin, symbolTable); + BuiltInVariable("gl_RayTminEXT", EbvRayTmin, symbolTable); + BuiltInVariable("gl_RayTmaxNV", EbvRayTmax, symbolTable); + BuiltInVariable("gl_RayTmaxEXT", EbvRayTmax, symbolTable); + BuiltInVariable("gl_HitTNV", EbvHitT, symbolTable); + BuiltInVariable("gl_HitTEXT", EbvHitT, symbolTable); + BuiltInVariable("gl_HitKindNV", EbvHitKind, symbolTable); + BuiltInVariable("gl_HitKindEXT", EbvHitKind, symbolTable); + BuiltInVariable("gl_ObjectToWorldNV", EbvObjectToWorld, symbolTable); + BuiltInVariable("gl_ObjectToWorldEXT", EbvObjectToWorld, symbolTable); + BuiltInVariable("gl_ObjectToWorld3x4EXT", EbvObjectToWorld3x4, symbolTable); + BuiltInVariable("gl_WorldToObjectNV", EbvWorldToObject, symbolTable); + BuiltInVariable("gl_WorldToObjectEXT", EbvWorldToObject, symbolTable); + BuiltInVariable("gl_WorldToObject3x4EXT", EbvWorldToObject3x4, symbolTable); + BuiltInVariable("gl_IncomingRayFlagsNV", EbvIncomingRayFlags, symbolTable); + BuiltInVariable("gl_IncomingRayFlagsEXT", EbvIncomingRayFlags, symbolTable); + BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable); // GL_ARB_shader_ballot symbolTable.setVariableExtensions("gl_SubGroupSizeARB", 1, &E_GL_ARB_shader_ballot); @@ -8470,6 +8835,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("average", EOpAverage); symbolTable.relateToOperator("averageRounded", EOpAverageRounded); symbolTable.relateToOperator("multiply32x16", EOpMul32x16); + symbolTable.relateToOperator("debugPrintfEXT", EOpDebugPrintf); + if (PureOperatorBuiltins) { symbolTable.relateToOperator("imageSize", EOpImageQuerySize); @@ -8768,6 +9135,33 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("dFdyCoarse", EOpDPdyCoarse); symbolTable.relateToOperator("fwidthCoarse", EOpFwidthCoarse); } + + if (profile != EEsProfile && version >= 460) { + symbolTable.relateToOperator("rayQueryInitializeEXT", EOpRayQueryInitialize); + symbolTable.relateToOperator("rayQueryTerminateEXT", EOpRayQueryTerminate); + symbolTable.relateToOperator("rayQueryGenerateIntersectionEXT", EOpRayQueryGenerateIntersection); + symbolTable.relateToOperator("rayQueryConfirmIntersectionEXT", EOpRayQueryConfirmIntersection); + symbolTable.relateToOperator("rayQueryProceedEXT", EOpRayQueryProceed); + symbolTable.relateToOperator("rayQueryGetIntersectionTypeEXT", EOpRayQueryGetIntersectionType); + symbolTable.relateToOperator("rayQueryGetRayTMinEXT", EOpRayQueryGetRayTMin); + symbolTable.relateToOperator("rayQueryGetRayFlagsEXT", EOpRayQueryGetRayFlags); + symbolTable.relateToOperator("rayQueryGetIntersectionTEXT", EOpRayQueryGetIntersectionT); + symbolTable.relateToOperator("rayQueryGetIntersectionInstanceCustomIndexEXT", EOpRayQueryGetIntersectionInstanceCustomIndex); + symbolTable.relateToOperator("rayQueryGetIntersectionInstanceIdEXT", EOpRayQueryGetIntersectionInstanceId); + symbolTable.relateToOperator("rayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetEXT", EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset); + symbolTable.relateToOperator("rayQueryGetIntersectionGeometryIndexEXT", EOpRayQueryGetIntersectionGeometryIndex); + symbolTable.relateToOperator("rayQueryGetIntersectionPrimitiveIndexEXT", EOpRayQueryGetIntersectionPrimitiveIndex); + symbolTable.relateToOperator("rayQueryGetIntersectionBarycentricsEXT", EOpRayQueryGetIntersectionBarycentrics); + symbolTable.relateToOperator("rayQueryGetIntersectionFrontFaceEXT", EOpRayQueryGetIntersectionFrontFace); + symbolTable.relateToOperator("rayQueryGetIntersectionCandidateAABBOpaqueEXT", EOpRayQueryGetIntersectionCandidateAABBOpaque); + symbolTable.relateToOperator("rayQueryGetIntersectionObjectRayDirectionEXT", EOpRayQueryGetIntersectionObjectRayDirection); + symbolTable.relateToOperator("rayQueryGetIntersectionObjectRayOriginEXT", EOpRayQueryGetIntersectionObjectRayOrigin); + symbolTable.relateToOperator("rayQueryGetWorldRayDirectionEXT", EOpRayQueryGetWorldRayDirection); + symbolTable.relateToOperator("rayQueryGetWorldRayOriginEXT", EOpRayQueryGetWorldRayOrigin); + symbolTable.relateToOperator("rayQueryGetIntersectionObjectToWorldEXT", EOpRayQueryGetIntersectionObjectToWorld); + symbolTable.relateToOperator("rayQueryGetIntersectionWorldToObjectEXT", EOpRayQueryGetIntersectionWorldToObject); + } + symbolTable.relateToOperator("interpolateAtCentroid", EOpInterpolateAtCentroid); symbolTable.relateToOperator("interpolateAtSample", EOpInterpolateAtSample); symbolTable.relateToOperator("interpolateAtOffset", EOpInterpolateAtOffset); @@ -8799,27 +9193,34 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("coopMatMulAddNV", EOpCooperativeMatrixMulAdd); break; - case EShLangRayGenNV: - case EShLangClosestHitNV: - case EShLangMissNV: + case EShLangRayGen: + case EShLangClosestHit: + case EShLangMiss: if (profile != EEsProfile && version >= 460) { - symbolTable.relateToOperator("traceNV", EOpTraceNV); - symbolTable.relateToOperator("executeCallableNV", EOpExecuteCallableNV); + symbolTable.relateToOperator("traceNV", EOpTrace); + symbolTable.relateToOperator("traceRayEXT", EOpTrace); + symbolTable.relateToOperator("executeCallableNV", EOpExecuteCallable); + symbolTable.relateToOperator("executeCallableEXT", EOpExecuteCallable); } break; - case EShLangIntersectNV: - if (profile != EEsProfile && version >= 460) - symbolTable.relateToOperator("reportIntersectionNV", EOpReportIntersectionNV); - break; - case EShLangAnyHitNV: + case EShLangIntersect: if (profile != EEsProfile && version >= 460) { - symbolTable.relateToOperator("ignoreIntersectionNV", EOpIgnoreIntersectionNV); - symbolTable.relateToOperator("terminateRayNV", EOpTerminateRayNV); + symbolTable.relateToOperator("reportIntersectionNV", EOpReportIntersection); + symbolTable.relateToOperator("reportIntersectionEXT", EOpReportIntersection); + } + break; + case EShLangAnyHit: + if (profile != EEsProfile && version >= 460) { + symbolTable.relateToOperator("ignoreIntersectionNV", EOpIgnoreIntersection); + symbolTable.relateToOperator("ignoreIntersectionEXT", EOpIgnoreIntersection); + symbolTable.relateToOperator("terminateRayNV", EOpTerminateRay); + symbolTable.relateToOperator("terminateRayEXT", EOpTerminateRay); } break; - case EShLangCallableNV: + case EShLangCallable: if (profile != EEsProfile && version >= 460) { - symbolTable.relateToOperator("executeCallableNV", EOpExecuteCallableNV); + symbolTable.relateToOperator("executeCallableNV", EOpExecuteCallable); + symbolTable.relateToOperator("executeCallableEXT", EOpExecuteCallable); } break; case EShLangMeshNV: @@ -8838,7 +9239,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion default: assert(false && "Language not supported"); } -#endif +#endif // !GLSLANG_WEB } // @@ -8853,6 +9254,10 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources) { #ifndef GLSLANG_WEB +#if defined(GLSLANG_ANGLE) + profile = ECoreProfile; + version = 450; +#endif if (profile != EEsProfile && version >= 430 && version < 440) { symbolTable.setVariableExtensions("gl_MaxTransformFeedbackBuffers", 1, &E_GL_ARB_enhanced_layouts); symbolTable.setVariableExtensions("gl_MaxTransformFeedbackInterleavedComponents", 1, &E_GL_ARB_enhanced_layouts); @@ -8876,6 +9281,16 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"), fragData)); SpecialQualifier("gl_FragData", EvqFragColor, EbvFragData, symbolTable); } + + // GL_EXT_blend_func_extended + if (profile == EEsProfile && version >= 100) { + symbolTable.setVariableExtensions("gl_MaxDualSourceDrawBuffersEXT", 1, &E_GL_EXT_blend_func_extended); + symbolTable.setVariableExtensions("gl_SecondaryFragColorEXT", 1, &E_GL_EXT_blend_func_extended); + symbolTable.setVariableExtensions("gl_SecondaryFragDataEXT", 1, &E_GL_EXT_blend_func_extended); + SpecialQualifier("gl_SecondaryFragColorEXT", EvqVaryingOut, EbvSecondaryFragColorEXT, symbolTable); + SpecialQualifier("gl_SecondaryFragDataEXT", EvqVaryingOut, EbvSecondaryFragDataEXT, symbolTable); + } + break; case EShLangTessControl: diff --git a/src/libraries/glslang/glslang/MachineIndependent/Intermediate.cpp b/src/libraries/glslang/glslang/MachineIndependent/Intermediate.cpp old mode 100755 new mode 100644 index d0f86e638..b8c220d78 --- a/src/libraries/glslang/glslang/MachineIndependent/Intermediate.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/Intermediate.cpp @@ -1,7 +1,7 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2015 LunarG, Inc. -// Copyright (C) 2015-2018 Google, Inc. +// Copyright (C) 2015-2020 Google, Inc. // Copyright (C) 2017 ARM Limited. // // All rights reserved. @@ -113,14 +113,14 @@ TIntermSymbol* TIntermediate::addSymbol(const TType& type, const TSourceLoc& loc // // Returns nullptr if the working conversions and promotions could not be found. // -TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc) +TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc& loc) { // No operations work on blocks if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock) return nullptr; // Convert "reference +/- int" and "reference - reference" to integer math - if ((op == EOpAdd || op == EOpSub) && extensionRequested(E_GL_EXT_buffer_reference2)) { + if (op == EOpAdd || op == EOpSub) { // No addressing math on struct with unsized array. if ((left->isReference() && left->getType().getReferentType()->containsUnsizedArray()) || @@ -140,43 +140,44 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn node = addBuiltInFunctionCall(loc, EOpConvUint64ToPtr, true, node, referenceType); return node; } - - if (op == EOpAdd && right->isReference() && isTypeInt(left->getBasicType())) { - const TType& referenceType = right->getType(); - TIntermConstantUnion* size = addConstantUnion((unsigned long long)computeBufferReferenceTypeSize(right->getType()), loc, true); - right = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, right, TType(EbtUint64)); - - left = createConversion(EbtInt64, left); - left = addBinaryMath(EOpMul, left, size, loc); - - TIntermTyped *node = addBinaryMath(op, left, right, loc); - node = addBuiltInFunctionCall(loc, EOpConvUint64ToPtr, true, node, referenceType); - return node; - } - - if (op == EOpSub && left->isReference() && right->isReference()) { - TIntermConstantUnion* size = addConstantUnion((long long)computeBufferReferenceTypeSize(left->getType()), loc, true); - - left = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, left, TType(EbtUint64)); - right = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, right, TType(EbtUint64)); - - left = addBuiltInFunctionCall(loc, EOpConvUint64ToInt64, true, left, TType(EbtInt64)); - right = addBuiltInFunctionCall(loc, EOpConvUint64ToInt64, true, right, TType(EbtInt64)); - - left = addBinaryMath(EOpSub, left, right, loc); - - TIntermTyped *node = addBinaryMath(EOpDiv, left, size, loc); - return node; - } - - // No other math operators supported on references - if (left->isReference() || right->isReference()) { - return nullptr; - } } + if (op == EOpAdd && right->isReference() && isTypeInt(left->getBasicType())) { + const TType& referenceType = right->getType(); + TIntermConstantUnion* size = + addConstantUnion((unsigned long long)computeBufferReferenceTypeSize(right->getType()), loc, true); + right = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, right, TType(EbtUint64)); + + left = createConversion(EbtInt64, left); + left = addBinaryMath(EOpMul, left, size, loc); + + TIntermTyped *node = addBinaryMath(op, left, right, loc); + node = addBuiltInFunctionCall(loc, EOpConvUint64ToPtr, true, node, referenceType); + return node; + } + + if (op == EOpSub && left->isReference() && right->isReference()) { + TIntermConstantUnion* size = + addConstantUnion((long long)computeBufferReferenceTypeSize(left->getType()), loc, true); + + left = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, left, TType(EbtUint64)); + right = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, right, TType(EbtUint64)); + + left = addBuiltInFunctionCall(loc, EOpConvUint64ToInt64, true, left, TType(EbtInt64)); + right = addBuiltInFunctionCall(loc, EOpConvUint64ToInt64, true, right, TType(EbtInt64)); + + left = addBinaryMath(EOpSub, left, right, loc); + + TIntermTyped *node = addBinaryMath(EOpDiv, left, size, loc); + return node; + } + + // No other math operators supported on references + if (left->isReference() || right->isReference()) + return nullptr; + // Try converting the children's base types to compatible types. - auto children = addConversion(op, left, right); + auto children = addPairConversion(op, left, right); left = std::get<0>(children); right = std::get<1>(children); @@ -226,13 +227,12 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn // // Low level: add binary node (no promotions or other argument modifications) // -TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc) const +TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, + const TSourceLoc& loc) const { // build the node TIntermBinary* node = new TIntermBinary(op); - if (loc.line == 0) - loc = left->getLoc(); - node->setLoc(loc); + node->setLoc(loc.line != 0 ? loc : left->getLoc()); node->setLeft(left); node->setRight(right); @@ -242,7 +242,8 @@ TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TI // // like non-type form, but sets node's type. // -TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc, const TType& type) const +TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, + const TSourceLoc& loc, const TType& type) const { TIntermBinary* node = addBinaryNode(op, left, right, loc); node->setType(type); @@ -252,12 +253,10 @@ TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TI // // Low level: add unary node (no promotions or other argument modifications) // -TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc loc) const +TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, const TSourceLoc& loc) const { TIntermUnary* node = new TIntermUnary(op); - if (loc.line == 0) - loc = child->getLoc(); - node->setLoc(loc); + node->setLoc(loc.line != 0 ? loc : child->getLoc()); node->setOperand(child); return node; @@ -266,7 +265,8 @@ TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, TSo // // like non-type form, but sets node's type. // -TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc loc, const TType& type) const +TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, const TSourceLoc& loc, const TType& type) + const { TIntermUnary* node = addUnaryNode(op, child, loc); node->setType(type); @@ -281,7 +281,8 @@ TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, TSo // Returns nullptr if the 'right' type could not be converted to match the 'left' type, // or the resulting operation cannot be properly promoted. // -TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc) +TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, + const TSourceLoc& loc) { // No block assignment if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock) @@ -290,9 +291,7 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm // Convert "reference += int" to "reference = reference + int". We need this because the // "reference + int" calculation involves a cast back to the original type, which makes it // not an lvalue. - if ((op == EOpAddAssign || op == EOpSubAssign) && left->isReference() && - extensionRequested(E_GL_EXT_buffer_reference2)) { - + if ((op == EOpAddAssign || op == EOpSubAssign) && left->isReference()) { if (!(right->getType().isScalar() && right->getType().isIntegerDomain())) return nullptr; @@ -338,7 +337,8 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm // Returns the added node. // The caller should set the type of the returned node. // -TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc loc) +TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, + const TSourceLoc& loc) { // caller should set the type return addBinaryNode(op, base, index, loc); @@ -349,7 +349,8 @@ TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermT // // Returns the added node. // -TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSourceLoc loc) +TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, + const TSourceLoc& loc) { if (child == 0) return nullptr; @@ -495,7 +496,8 @@ TIntermTyped* TIntermediate::addBuiltInFunctionCall(const TSourceLoc& loc, TOper // Returns an aggregate node, which could be the one passed in if // it was already an aggregate. // -TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TType& type, TSourceLoc loc) +TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TType& type, + const TSourceLoc& loc) { TIntermAggregate* aggNode; @@ -510,8 +512,6 @@ TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator o // aggNode = new TIntermAggregate(); aggNode->getSequence().push_back(node); - if (loc.line == 0) - loc = node->getLoc(); } } else aggNode = new TIntermAggregate(); @@ -520,8 +520,8 @@ TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator o // Set the operator. // aggNode->setOperator(op); - if (loc.line != 0) - aggNode->setLoc(loc); + if (loc.line != 0 || node != nullptr) + aggNode->setLoc(loc.line != 0 ? loc : node->getLoc()); aggNode->setType(type); @@ -538,7 +538,7 @@ bool TIntermediate::isConversionAllowed(TOperator op, TIntermTyped* node) const return false; case EbtAtomicUint: case EbtSampler: - case EbtAccStructNV: + case EbtAccStruct: // opaque types can be passed to functions if (op == EOpFunction) break; @@ -819,22 +819,25 @@ TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped node->getBasicType() == EbtFloat || node->getBasicType() == EbtDouble); - if (! getArithemeticInt8Enabled()) { - if (((convertTo == EbtInt8 || convertTo == EbtUint8) && ! convertFromIntTypes) || - ((node->getBasicType() == EbtInt8 || node->getBasicType() == EbtUint8) && ! convertToIntTypes)) + if (((convertTo == EbtInt8 || convertTo == EbtUint8) && ! convertFromIntTypes) || + ((node->getBasicType() == EbtInt8 || node->getBasicType() == EbtUint8) && ! convertToIntTypes)) { + if (! getArithemeticInt8Enabled()) { return nullptr; + } } - if (! getArithemeticInt16Enabled()) { - if (((convertTo == EbtInt16 || convertTo == EbtUint16) && ! convertFromIntTypes) || - ((node->getBasicType() == EbtInt16 || node->getBasicType() == EbtUint16) && ! convertToIntTypes)) + if (((convertTo == EbtInt16 || convertTo == EbtUint16) && ! convertFromIntTypes) || + ((node->getBasicType() == EbtInt16 || node->getBasicType() == EbtUint16) && ! convertToIntTypes)) { + if (! getArithemeticInt16Enabled()) { return nullptr; + } } - if (! getArithemeticFloat16Enabled()) { - if ((convertTo == EbtFloat16 && ! convertFromFloatTypes) || - (node->getBasicType() == EbtFloat16 && ! convertToFloatTypes)) + if ((convertTo == EbtFloat16 && ! convertFromFloatTypes) || + (node->getBasicType() == EbtFloat16 && ! convertToFloatTypes)) { + if (! getArithemeticFloat16Enabled()) { return nullptr; + } } #endif @@ -887,7 +890,7 @@ TIntermTyped* TIntermediate::addConversion(TBasicType convertTo, TIntermTyped* n // Returns the converted pair of nodes. // Returns when there is no conversion. std::tuple -TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* node1) +TIntermediate::addPairConversion(TOperator op, TIntermTyped* node0, TIntermTyped* node1) { if (!isConversionAllowed(op, node0) || !isConversionAllowed(op, node1)) return std::make_tuple(nullptr, nullptr); @@ -940,7 +943,7 @@ TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* no if (node0->getBasicType() == node1->getBasicType()) return std::make_tuple(node0, node1); - promoteTo = getConversionDestinatonType(node0->getBasicType(), node1->getBasicType(), op); + promoteTo = getConversionDestinationType(node0->getBasicType(), node1->getBasicType(), op); if (std::get<0>(promoteTo) == EbtNumTypes || std::get<1>(promoteTo) == EbtNumTypes) return std::make_tuple(nullptr, nullptr); @@ -1040,64 +1043,30 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt // Note: callers are responsible for other aspects of shape, // like vector and matrix sizes. - TBasicType promoteTo; - // GL_EXT_shader_16bit_storage can't do OpConstantComposite with - // 16-bit types, so disable promotion for those types. - bool canPromoteConstant = true; - switch (op) { // // Explicit conversions (unary operations) // case EOpConstructBool: - promoteTo = EbtBool; - break; case EOpConstructFloat: - promoteTo = EbtFloat; - break; case EOpConstructInt: - promoteTo = EbtInt; - break; case EOpConstructUint: - promoteTo = EbtUint; - break; #ifndef GLSLANG_WEB case EOpConstructDouble: - promoteTo = EbtDouble; - break; case EOpConstructFloat16: - promoteTo = EbtFloat16; - canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float16); - break; case EOpConstructInt8: - promoteTo = EbtInt8; - canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8); - break; case EOpConstructUint8: - promoteTo = EbtUint8; - canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8); - break; case EOpConstructInt16: - promoteTo = EbtInt16; - canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16); - break; case EOpConstructUint16: - promoteTo = EbtUint16; - canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16); - break; case EOpConstructInt64: - promoteTo = EbtInt64; - break; case EOpConstructUint64: - promoteTo = EbtUint64; break; + #endif + // + // Implicit conversions + // case EOpLogicalNot: case EOpFunctionCall: @@ -1152,9 +1121,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt if (type.getBasicType() == node->getType().getBasicType()) return node; - if (canImplicitlyPromote(node->getBasicType(), type.getBasicType(), op)) - promoteTo = type.getBasicType(); - else + if (! canImplicitlyPromote(node->getBasicType(), type.getBasicType(), op)) return nullptr; break; @@ -1164,9 +1131,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt case EOpLeftShiftAssign: case EOpRightShiftAssign: { - if (getSource() == EShSourceHlsl && node->getType().getBasicType() == EbtBool) - promoteTo = type.getBasicType(); - else { + if (!(getSource() == EShSourceHlsl && node->getType().getBasicType() == EbtBool)) { if (isTypeInt(type.getBasicType()) && isTypeInt(node->getBasicType())) return node; else @@ -1184,13 +1149,44 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt return nullptr; } + bool canPromoteConstant = true; +#ifndef GLSLANG_WEB + // GL_EXT_shader_16bit_storage can't do OpConstantComposite with + // 16-bit types, so disable promotion for those types. + // Many issues with this, from JohnK: + // - this isn't really right to discuss SPIR-V here + // - this could easily be entirely about scalars, so is overstepping + // - we should be looking at what the shader asked for, and saying whether or + // not it can be done, in the parser, by calling requireExtensions(), not + // changing language sementics on the fly by asking what extensions are in use + // - at the time of this writing (14-Aug-2020), no test results are changed by this. + switch (op) { + case EOpConstructFloat16: + canPromoteConstant = numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_float16); + break; + case EOpConstructInt8: + case EOpConstructUint8: + canPromoteConstant = numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int8); + break; + case EOpConstructInt16: + case EOpConstructUint16: + canPromoteConstant = numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int16); + break; + default: + break; + } +#endif + if (canPromoteConstant && node->getAsConstantUnion()) - return promoteConstantUnion(promoteTo, node->getAsConstantUnion()); + return promoteConstantUnion(type.getBasicType(), node->getAsConstantUnion()); // // Add a new newNode for the conversion. // - TIntermTyped* newNode = createConversion(promoteTo, node); + TIntermTyped* newNode = createConversion(type.getBasicType(), node); return newNode; } @@ -1620,7 +1616,7 @@ bool TIntermediate::isFPIntegralConversion(TBasicType from, TBasicType to) const // bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperator op) const { - if (isEsProfile() || version == 110) + if ((isEsProfile() && version < 310 ) || version == 110) return false; if (from == to) @@ -1659,46 +1655,51 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat } } - bool explicitTypesEnabled = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int32) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int64) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float16) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float32) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float64); - - if (explicitTypesEnabled) { - // integral promotions - if (isIntegralPromotion(from, to)) { + if (getSource() == EShSourceHlsl) { + // HLSL + if (from == EbtBool && (to == EbtInt || to == EbtUint || to == EbtFloat)) return true; - } + } else { + // GLSL + if (isIntegralPromotion(from, to) || + isFPPromotion(from, to) || + isIntegralConversion(from, to) || + isFPConversion(from, to) || + isFPIntegralConversion(from, to)) { - // floating-point promotions - if (isFPPromotion(from, to)) { - return true; - } - - // integral conversions - if (isIntegralConversion(from, to)) { - return true; - } - - // floating-point conversions - if (isFPConversion(from, to)) { - return true; - } - - // floating-integral conversions - if (isFPIntegralConversion(from, to)) { - return true; - } - - // hlsl supported conversions - if (getSource() == EShSourceHlsl) { - if (from == EbtBool && (to == EbtInt || to == EbtUint || to == EbtFloat)) + if (numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int8) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int16) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int32) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int64) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_float16) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_float32) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_float64)) { return true; + } } + } + + if (isEsProfile()) { + switch (to) { + case EbtFloat: + switch (from) { + case EbtInt: + case EbtUint: + return numericFeatures.contains(TNumericFeatures::shader_implicit_conversions); + default: + return false; + } + case EbtUint: + switch (from) { + case EbtInt: + return numericFeatures.contains(TNumericFeatures::shader_implicit_conversions); + default: + return false; + } + default: + return false; + } } else { switch (to) { case EbtDouble: @@ -1708,13 +1709,14 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat case EbtInt64: case EbtUint64: case EbtFloat: - case EbtDouble: - return true; + return version >= 400 || numericFeatures.contains(TNumericFeatures::gpu_shader_fp64); case EbtInt16: case EbtUint16: - return extensionRequested(E_GL_AMD_gpu_shader_int16); + return (version >= 400 || numericFeatures.contains(TNumericFeatures::gpu_shader_fp64)) && + numericFeatures.contains(TNumericFeatures::gpu_shader_int16); case EbtFloat16: - return extensionRequested(E_GL_AMD_gpu_shader_half_float); + return (version >= 400 || numericFeatures.contains(TNumericFeatures::gpu_shader_fp64)) && + numericFeatures.contains(TNumericFeatures::gpu_shader_half_float); default: return false; } @@ -1722,16 +1724,14 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat switch (from) { case EbtInt: case EbtUint: - case EbtFloat: return true; case EbtBool: return getSource() == EShSourceHlsl; case EbtInt16: case EbtUint16: - return extensionRequested(E_GL_AMD_gpu_shader_int16); + return numericFeatures.contains(TNumericFeatures::gpu_shader_int16); case EbtFloat16: - return - extensionRequested(E_GL_AMD_gpu_shader_half_float) || + return numericFeatures.contains(TNumericFeatures::gpu_shader_half_float) || getSource() == EShSourceHlsl; default: return false; @@ -1739,25 +1739,21 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat case EbtUint: switch (from) { case EbtInt: - return version >= 400 || getSource() == EShSourceHlsl; - case EbtUint: - return true; + return version >= 400 || getSource() == EShSourceHlsl; case EbtBool: return getSource() == EShSourceHlsl; case EbtInt16: case EbtUint16: - return extensionRequested(E_GL_AMD_gpu_shader_int16); + return numericFeatures.contains(TNumericFeatures::gpu_shader_int16); default: return false; } case EbtInt: switch (from) { - case EbtInt: - return true; case EbtBool: return getSource() == EShSourceHlsl; case EbtInt16: - return extensionRequested(E_GL_AMD_gpu_shader_int16); + return numericFeatures.contains(TNumericFeatures::gpu_shader_int16); default: return false; } @@ -1766,21 +1762,19 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat case EbtInt: case EbtUint: case EbtInt64: - case EbtUint64: return true; case EbtInt16: case EbtUint16: - return extensionRequested(E_GL_AMD_gpu_shader_int16); + return numericFeatures.contains(TNumericFeatures::gpu_shader_int16); default: return false; } case EbtInt64: switch (from) { case EbtInt: - case EbtInt64: return true; case EbtInt16: - return extensionRequested(E_GL_AMD_gpu_shader_int16); + return numericFeatures.contains(TNumericFeatures::gpu_shader_int16); default: return false; } @@ -1788,9 +1782,7 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat switch (from) { case EbtInt16: case EbtUint16: - return extensionRequested(E_GL_AMD_gpu_shader_int16); - case EbtFloat16: - return extensionRequested(E_GL_AMD_gpu_shader_half_float); + return numericFeatures.contains(TNumericFeatures::gpu_shader_int16); default: break; } @@ -1798,8 +1790,7 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat case EbtUint16: switch (from) { case EbtInt16: - case EbtUint16: - return extensionRequested(E_GL_AMD_gpu_shader_int16); + return numericFeatures.contains(TNumericFeatures::gpu_shader_int16); default: break; } @@ -1926,12 +1917,14 @@ static TBasicType getCorrespondingUnsignedType(TBasicType type) // integer type corresponding to the type of the operand with signed // integer type. -std::tuple TIntermediate::getConversionDestinatonType(TBasicType type0, TBasicType type1, TOperator op) const +std::tuple TIntermediate::getConversionDestinationType(TBasicType type0, TBasicType type1, TOperator op) const { TBasicType res0 = EbtNumTypes; TBasicType res1 = EbtNumTypes; - if (isEsProfile() || version == 110) + if ((isEsProfile() && + (version < 310 || !numericFeatures.contains(TNumericFeatures::shader_implicit_conversions))) || + version == 110) return std::make_tuple(res0, res1); if (getSource() == EShSourceHlsl) { @@ -2463,7 +2456,7 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true // // Get compatible types. // - auto children = addConversion(EOpSequence, trueBlock, falseBlock); + auto children = addPairConversion(EOpSequence, trueBlock, falseBlock); trueBlock = std::get<0>(children); falseBlock = std::get<1>(children); @@ -2750,6 +2743,22 @@ TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expres return node; } +// Propagate precision from formal function return type to actual return type, +// and on to its subtree. +void TIntermBranch::updatePrecision(TPrecisionQualifier parentPrecision) +{ + TIntermTyped* exp = getExpression(); + if (exp == nullptr) + return; + + if (exp->getBasicType() == EbtInt || exp->getBasicType() == EbtUint || + exp->getBasicType() == EbtFloat || exp->getBasicType() == EbtFloat16) { + if (parentPrecision != EpqNone && exp->getQualifier().precision == EpqNone) { + exp->propagatePrecision(parentPrecision); + } + } +} + // // This is to be executed after the final root is put on top by the parsing // process. @@ -2774,6 +2783,9 @@ bool TIntermediate::postProcess(TIntermNode* root, EShLanguage /*language*/) case EShTexSampTransUpgradeTextureRemoveSampler: performTextureUpgradeAndSamplerRemovalTransformation(root); break; + case EShTexSampTransCount: + assert(0); + break; } #endif @@ -3234,10 +3246,17 @@ bool TIntermediate::promoteUnary(TIntermUnary& node) return false; break; - default: - if (operand->getBasicType() != EbtFloat) + // HLSL uses this path for initial function signature finding for built-ins + // taking a single argument, which generally don't participate in + // operator-based type promotion (type conversion will occur later). + // For now, scalar argument cases are relying on the setType() call below. + if (getSource() == EShSourceHlsl) + break; + // GLSL only allows integer arguments for the cases identified above in the + // case statements. + if (operand->getBasicType() != EbtFloat) return false; } @@ -3247,9 +3266,11 @@ bool TIntermediate::promoteUnary(TIntermUnary& node) return true; } +// Propagate precision qualifiers *up* from children to parent. void TIntermUnary::updatePrecision() { - if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat || getBasicType() == EbtFloat16) { + if (getBasicType() == EbtInt || getBasicType() == EbtUint || + getBasicType() == EbtFloat || getBasicType() == EbtFloat16) { if (operand->getQualifier().precision > getQualifier().precision) getQualifier().precision = operand->getQualifier().precision; } @@ -3745,9 +3766,12 @@ bool TIntermediate::promoteAggregate(TIntermAggregate& node) return false; } +// Propagate precision qualifiers *up* from children to parent, and then +// back *down* again to the children's subtrees. void TIntermBinary::updatePrecision() { - if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat || getBasicType() == EbtFloat16) { + if (getBasicType() == EbtInt || getBasicType() == EbtUint || + getBasicType() == EbtFloat || getBasicType() == EbtFloat16) { getQualifier().precision = std::max(right->getQualifier().precision, left->getQualifier().precision); if (getQualifier().precision != EpqNone) { left->propagatePrecision(getQualifier().precision); @@ -3756,9 +3780,14 @@ void TIntermBinary::updatePrecision() } } +// Recursively propagate precision qualifiers *down* the subtree of the current node, +// until reaching a node that already has a precision qualifier or otherwise does +// not participate in precision propagation. void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision) { - if (getQualifier().precision != EpqNone || (getBasicType() != EbtInt && getBasicType() != EbtUint && getBasicType() != EbtFloat && getBasicType() != EbtFloat16)) + if (getQualifier().precision != EpqNone || + (getBasicType() != EbtInt && getBasicType() != EbtUint && + getBasicType() != EbtFloat && getBasicType() != EbtFloat16)) return; getQualifier().precision = newPrecision; diff --git a/src/libraries/glslang/glslang/MachineIndependent/LiveTraverser.h b/src/libraries/glslang/glslang/MachineIndependent/LiveTraverser.h index 7333bc964..9b39b5983 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/LiveTraverser.h +++ b/src/libraries/glslang/glslang/MachineIndependent/LiveTraverser.h @@ -74,14 +74,33 @@ public: for (unsigned int f = 0; f < globals.size(); ++f) { TIntermAggregate* candidate = globals[f]->getAsAggregate(); if (candidate && candidate->getOp() == EOpFunction && candidate->getName() == name) { - functions.push_back(candidate); + destinations.push_back(candidate); break; } } } - typedef std::list TFunctionStack; - TFunctionStack functions; + void pushGlobalReference(const TString& name) + { + TIntermSequence& globals = intermediate.getTreeRoot()->getAsAggregate()->getSequence(); + for (unsigned int f = 0; f < globals.size(); ++f) { + TIntermAggregate* candidate = globals[f]->getAsAggregate(); + if (candidate && candidate->getOp() == EOpSequence && + candidate->getSequence().size() == 1 && + candidate->getSequence()[0]->getAsBinaryNode()) { + TIntermBinary* binary = candidate->getSequence()[0]->getAsBinaryNode(); + TIntermSymbol* symbol = binary->getLeft()->getAsSymbolNode(); + if (symbol && symbol->getQualifier().storage == EvqGlobal && + symbol->getName() == name) { + destinations.push_back(candidate); + break; + } + } + } + } + + typedef std::list TDestinationStack; + TDestinationStack destinations; protected: // To catch which function calls are not dead, and hence which functions must be visited. @@ -117,16 +136,27 @@ protected: // and only visit each function once. void addFunctionCall(TIntermAggregate* call) { - // // just use the map to ensure we process each function at most once + // just use the map to ensure we process each function at most once if (liveFunctions.find(call->getName()) == liveFunctions.end()) { liveFunctions.insert(call->getName()); pushFunction(call->getName()); } } + void addGlobalReference(const TString& name) + { + // just use the map to ensure we process each global at most once + if (liveGlobals.find(name) == liveGlobals.end()) { + liveGlobals.insert(name); + pushGlobalReference(name); + } + } + const TIntermediate& intermediate; typedef std::unordered_set TLiveFunctions; TLiveFunctions liveFunctions; + typedef std::unordered_set TLiveGlobals; + TLiveGlobals liveGlobals; bool traverseAll; private: diff --git a/src/libraries/glslang/glslang/MachineIndependent/ParseContextBase.cpp b/src/libraries/glslang/glslang/MachineIndependent/ParseContextBase.cpp index 282ecca0e..b46400914 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/ParseContextBase.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/ParseContextBase.cpp @@ -157,11 +157,11 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op, case EvqBuffer: if (node->getQualifier().isReadOnly()) message = "can't modify a readonly buffer"; - if (node->getQualifier().isShaderRecordNV()) + if (node->getQualifier().isShaderRecord()) message = "can't modify a shaderrecordnv qualified buffer"; break; - case EvqHitAttrNV: - if (language != EShLangIntersectNV) + case EvqHitAttr: + if (language != EShLangIntersect) message = "cannot modify hitAttributeNV in this stage"; break; #endif @@ -181,9 +181,12 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op, case EbtAtomicUint: message = "can't modify an atomic_uint"; break; - case EbtAccStructNV: + case EbtAccStruct: message = "can't modify accelerationStructureNV"; break; + case EbtRayQuery: + message = "can't modify rayQueryEXT"; + break; #endif default: break; diff --git a/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp b/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp index a2224e160..86a5a3786 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp @@ -3,6 +3,7 @@ // Copyright (C) 2012-2015 LunarG, Inc. // Copyright (C) 2015-2018 Google, Inc. // Copyright (C) 2017, 2019 ARM Limited. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -245,7 +246,9 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector& else if (tokens[2].compare("off") == 0) contextPragma.optimize = false; else { - error(loc, "\"on\" or \"off\" expected after '(' for 'optimize' pragma", "#pragma", ""); + if(relaxedErrors()) + // If an implementation does not recognize the tokens following #pragma, then it will ignore that pragma. + warn(loc, "\"on\" or \"off\" expected after '(' for 'optimize' pragma", "#pragma", ""); return; } @@ -269,7 +272,9 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector& else if (tokens[2].compare("off") == 0) contextPragma.debug = false; else { - error(loc, "\"on\" or \"off\" expected after '(' for 'debug' pragma", "#pragma", ""); + if(relaxedErrors()) + // If an implementation does not recognize the tokens following #pragma, then it will ignore that pragma. + warn(loc, "\"on\" or \"off\" expected after '(' for 'debug' pragma", "#pragma", ""); return; } @@ -427,8 +432,18 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn #ifndef GLSLANG_WEB if (base->isReference() && ! base->isArray()) { requireExtensions(loc, 1, &E_GL_EXT_buffer_reference2, "buffer reference indexing"); - result = intermediate.addBinaryMath(EOpAdd, base, index, loc); - result->setType(base->getType()); + if (base->getType().getReferentType()->containsUnsizedArray()) { + error(loc, "cannot index reference to buffer containing an unsized array", "", ""); + result = nullptr; + } else { + result = intermediate.addBinaryMath(EOpAdd, base, index, loc); + if (result != nullptr) + result->setType(base->getType()); + } + if (result == nullptr) { + error(loc, "cannot index buffer reference", "", ""); + result = intermediate.addConstantUnion(0.0, EbtFloat, loc); + } return result; } if (base->getAsSymbolNode() && isIoResizeArray(base->getType())) @@ -740,8 +755,11 @@ TIntermTyped* TParseContext::handleBinaryMath(const TSourceLoc& loc, const char* } TIntermTyped* result = nullptr; - if (allowed) + if (allowed) { + if ((left->isReference() || right->isReference())) + requireExtensions(loc, 1, &E_GL_EXT_buffer_reference2, "buffer reference math"); result = intermediate.addBinaryMath(op, left, right, loc); + } if (result == nullptr) binaryOpError(loc, str, left->getCompleteString(), right->getCompleteString()); @@ -821,50 +839,7 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm TIntermTyped* result = base; if ((base->isVector() || base->isScalar()) && (base->isFloatingDomain() || base->isIntegerDomain() || base->getBasicType() == EbtBool)) { - if (base->isScalar()) { - const char* dotFeature = "scalar swizzle"; - requireProfile(loc, ~EEsProfile, dotFeature); - profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, dotFeature); - } - - TSwizzleSelectors selectors; - parseSwizzleSelector(loc, field, base->getVectorSize(), selectors); - - if (base->isVector() && selectors.size() != 1 && base->getType().contains16BitFloat()) - requireFloat16Arithmetic(loc, ".", "can't swizzle types containing float16"); - if (base->isVector() && selectors.size() != 1 && base->getType().contains16BitInt()) - requireInt16Arithmetic(loc, ".", "can't swizzle types containing (u)int16"); - if (base->isVector() && selectors.size() != 1 && base->getType().contains8BitInt()) - requireInt8Arithmetic(loc, ".", "can't swizzle types containing (u)int8"); - - if (base->isScalar()) { - if (selectors.size() == 1) - return result; - else { - TType type(base->getBasicType(), EvqTemporary, selectors.size()); - // Swizzle operations propagate specialization-constantness - if (base->getQualifier().isSpecConstant()) - type.getQualifier().makeSpecConstant(); - return addConstructor(loc, base, type); - } - } - - if (base->getType().getQualifier().isFrontEndConstant()) - result = intermediate.foldSwizzle(base, selectors, loc); - else { - if (selectors.size() == 1) { - TIntermTyped* index = intermediate.addConstantUnion(selectors[0], loc); - result = intermediate.addIndex(EOpIndexDirect, base, index, loc); - result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision)); - } else { - TIntermTyped* index = intermediate.addSwizzle(selectors, loc); - result = intermediate.addIndex(EOpVectorSwizzle, base, index, loc); - result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision, selectors.size())); - } - // Swizzle operations propagate specialization-constantness - if (base->getType().getQualifier().isSpecConstant()) - result->getWritableType().getQualifier().makeSpecConstant(); - } + result = handleDotSwizzle(loc, base, field); } else if (base->isStruct() || base->isReference()) { const TTypeList* fields = base->isReference() ? base->getType().getReferentType()->getStruct() : @@ -905,6 +880,60 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm return result; } +// +// Handle seeing a base.swizzle, a subset of base.identifier in the grammar. +// +TIntermTyped* TParseContext::handleDotSwizzle(const TSourceLoc& loc, TIntermTyped* base, const TString& field) +{ + TIntermTyped* result = base; + if (base->isScalar()) { + const char* dotFeature = "scalar swizzle"; + requireProfile(loc, ~EEsProfile, dotFeature); + profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, dotFeature); + } + + TSwizzleSelectors selectors; + parseSwizzleSelector(loc, field, base->getVectorSize(), selectors); + + if (base->isVector() && selectors.size() != 1 && base->getType().contains16BitFloat()) + requireFloat16Arithmetic(loc, ".", "can't swizzle types containing float16"); + if (base->isVector() && selectors.size() != 1 && base->getType().contains16BitInt()) + requireInt16Arithmetic(loc, ".", "can't swizzle types containing (u)int16"); + if (base->isVector() && selectors.size() != 1 && base->getType().contains8BitInt()) + requireInt8Arithmetic(loc, ".", "can't swizzle types containing (u)int8"); + + if (base->isScalar()) { + if (selectors.size() == 1) + return result; + else { + TType type(base->getBasicType(), EvqTemporary, selectors.size()); + // Swizzle operations propagate specialization-constantness + if (base->getQualifier().isSpecConstant()) + type.getQualifier().makeSpecConstant(); + return addConstructor(loc, base, type); + } + } + + if (base->getType().getQualifier().isFrontEndConstant()) + result = intermediate.foldSwizzle(base, selectors, loc); + else { + if (selectors.size() == 1) { + TIntermTyped* index = intermediate.addConstantUnion(selectors[0], loc); + result = intermediate.addIndex(EOpIndexDirect, base, index, loc); + result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision)); + } else { + TIntermTyped* index = intermediate.addSwizzle(selectors, loc); + result = intermediate.addIndex(EOpVectorSwizzle, base, index, loc); + result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision, selectors.size())); + } + // Swizzle operations propagate specialization-constantness + if (base->getType().getQualifier().isSpecConstant()) + result->getWritableType().getQualifier().makeSpecConstant(); + } + + return result; +} + void TParseContext::blockMemberExtensionCheck(const TSourceLoc& loc, const TIntermTyped* base, int member, const TString& memberName) { // a block that needs extension checking is either 'base', or if arrayed, @@ -1273,7 +1302,7 @@ TIntermTyped* TParseContext::handleBuiltInFunctionCall(TSourceLoc loc, TIntermNo TIntermTyped *result = intermediate.addBuiltInFunctionCall(loc, function.getBuiltInOp(), function.getParamCount() == 1, arguments, function.getType()); - if (obeyPrecisionQualifiers()) + if (result != nullptr && obeyPrecisionQualifiers()) computeBuiltinPrecisions(*result, function); if (result == nullptr) { @@ -1353,6 +1382,9 @@ void TParseContext::computeBuiltinPrecisions(TIntermTyped& node, const TFunction case EOpInterpolateAtSample: numArgs = 1; break; + case EOpDebugPrintf: + numArgs = 0; + break; default: break; } @@ -1390,23 +1422,28 @@ TIntermNode* TParseContext::handleReturnValue(const TSourceLoc& loc, TIntermType #endif functionReturnsValue = true; + TIntermBranch* branch = nullptr; if (currentFunctionType->getBasicType() == EbtVoid) { error(loc, "void function cannot return a value", "return", ""); - return intermediate.addBranch(EOpReturn, loc); + branch = intermediate.addBranch(EOpReturn, loc); } else if (*currentFunctionType != value->getType()) { TIntermTyped* converted = intermediate.addConversion(EOpReturn, *currentFunctionType, value); if (converted) { if (*currentFunctionType != converted->getType()) error(loc, "cannot convert return value to function return type", "return", ""); if (version < 420) - warn(loc, "type conversion on return values was not explicitly allowed until version 420", "return", ""); - return intermediate.addBranch(EOpReturn, converted, loc); + warn(loc, "type conversion on return values was not explicitly allowed until version 420", + "return", ""); + branch = intermediate.addBranch(EOpReturn, converted, loc); } else { error(loc, "type does not match, or is not convertible to, the function's return type", "return", ""); - return intermediate.addBranch(EOpReturn, value, loc); + branch = intermediate.addBranch(EOpReturn, value, loc); } } else - return intermediate.addBranch(EOpReturn, value, loc); + branch = intermediate.addBranch(EOpReturn, value, loc); + + branch->updatePrecision(currentFunctionType->getQualifier().precision); + return branch; } // See if the operation is being done in an illegal location. @@ -1650,6 +1687,14 @@ TIntermTyped* TParseContext::addOutputArgumentConversions(const TFunction& funct #endif } +TIntermTyped* TParseContext::addAssign(const TSourceLoc& loc, TOperator op, TIntermTyped* left, TIntermTyped* right) +{ + if ((op == EOpAddAssign || op == EOpSubAssign) && left->isReference()) + requireExtensions(loc, 1, &E_GL_EXT_buffer_reference2, "+= and -= on a buffer reference"); + + return intermediate.addAssign(op, left, right, loc); +} + void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction& fnCandidate, const TIntermOperator& callNode) { const TIntermSequence* argp = &callNode.getAsAggregate()->getSequence(); @@ -1672,6 +1717,9 @@ void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction& unsigned int semantics = 0, storageClassSemantics = 0; unsigned int semantics2 = 0, storageClassSemantics2 = 0; + const TIntermTyped* arg0 = (*argp)[0]->getAsTyped(); + const bool isMS = arg0->getBasicType() == EbtSampler && arg0->getType().getSampler().isMultiSample(); + // Grab the semantics and storage class semantics from the operands, based on opcode switch (callNode.getOp()) { case EOpAtomicAdd: @@ -1704,18 +1752,18 @@ void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction& case EOpImageAtomicXor: case EOpImageAtomicExchange: case EOpImageAtomicStore: - storageClassSemantics = (*argp)[4]->getAsConstantUnion()->getConstArray()[0].getIConst(); - semantics = (*argp)[5]->getAsConstantUnion()->getConstArray()[0].getIConst(); + storageClassSemantics = (*argp)[isMS ? 5 : 4]->getAsConstantUnion()->getConstArray()[0].getIConst(); + semantics = (*argp)[isMS ? 6 : 5]->getAsConstantUnion()->getConstArray()[0].getIConst(); break; case EOpImageAtomicLoad: - storageClassSemantics = (*argp)[3]->getAsConstantUnion()->getConstArray()[0].getIConst(); - semantics = (*argp)[4]->getAsConstantUnion()->getConstArray()[0].getIConst(); + storageClassSemantics = (*argp)[isMS ? 4 : 3]->getAsConstantUnion()->getConstArray()[0].getIConst(); + semantics = (*argp)[isMS ? 5 : 4]->getAsConstantUnion()->getConstArray()[0].getIConst(); break; case EOpImageAtomicCompSwap: - storageClassSemantics = (*argp)[5]->getAsConstantUnion()->getConstArray()[0].getIConst(); - semantics = (*argp)[6]->getAsConstantUnion()->getConstArray()[0].getIConst(); - storageClassSemantics2 = (*argp)[7]->getAsConstantUnion()->getConstArray()[0].getIConst(); - semantics2 = (*argp)[8]->getAsConstantUnion()->getConstArray()[0].getIConst(); + storageClassSemantics = (*argp)[isMS ? 6 : 5]->getAsConstantUnion()->getConstArray()[0].getIConst(); + semantics = (*argp)[isMS ? 7 : 6]->getAsConstantUnion()->getConstArray()[0].getIConst(); + storageClassSemantics2 = (*argp)[isMS ? 8 : 7]->getAsConstantUnion()->getConstArray()[0].getIConst(); + semantics2 = (*argp)[isMS ? 9 : 8]->getAsConstantUnion()->getConstArray()[0].getIConst(); break; case EOpBarrier: @@ -2006,18 +2054,20 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan if (arg > 0) { #ifndef GLSLANG_WEB - bool f16ShadowCompare = (*argp)[1]->getAsTyped()->getBasicType() == EbtFloat16 && arg0->getType().getSampler().shadow; + bool f16ShadowCompare = (*argp)[1]->getAsTyped()->getBasicType() == EbtFloat16 && + arg0->getType().getSampler().shadow; if (f16ShadowCompare) ++arg; #endif - if (! (*argp)[arg]->getAsConstantUnion()) + if (! (*argp)[arg]->getAsTyped()->getQualifier().isConstant()) error(loc, "argument must be compile-time constant", "texel offset", ""); - else { + else if ((*argp)[arg]->getAsConstantUnion()) { const TType& type = (*argp)[arg]->getAsTyped()->getType(); for (int c = 0; c < type.getVectorSize(); ++c) { int offset = (*argp)[arg]->getAsConstantUnion()->getConstArray()[c].getIConst(); if (offset > resources.maxProgramTexelOffset || offset < resources.minProgramTexelOffset) - error(loc, "value is out of range:", "texel offset", "[gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]"); + error(loc, "value is out of range:", "texel offset", + "[gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]"); } } } @@ -2026,15 +2076,32 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan } #ifndef GLSLANG_WEB - case EOpTraceNV: + case EOpTrace: if (!(*argp)[10]->getAsConstantUnion()) error(loc, "argument must be compile-time constant", "payload number", ""); break; - case EOpExecuteCallableNV: + case EOpExecuteCallable: if (!(*argp)[1]->getAsConstantUnion()) error(loc, "argument must be compile-time constant", "callable data number", ""); break; + case EOpRayQueryGetIntersectionType: + case EOpRayQueryGetIntersectionT: + case EOpRayQueryGetIntersectionInstanceCustomIndex: + case EOpRayQueryGetIntersectionInstanceId: + case EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset: + case EOpRayQueryGetIntersectionGeometryIndex: + case EOpRayQueryGetIntersectionPrimitiveIndex: + case EOpRayQueryGetIntersectionBarycentrics: + case EOpRayQueryGetIntersectionFrontFace: + case EOpRayQueryGetIntersectionObjectRayDirection: + case EOpRayQueryGetIntersectionObjectRayOrigin: + case EOpRayQueryGetIntersectionObjectToWorld: + case EOpRayQueryGetIntersectionWorldToObject: + if (!(*argp)[1]->getAsConstantUnion()) + error(loc, "argument must be compile-time constant", "committed", ""); + break; + case EOpTextureQuerySamples: case EOpImageQuerySamples: // GL_ARB_shader_texture_image_samples @@ -2058,7 +2125,14 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan if (imageType.getQualifier().getFormat() != ElfR32i && imageType.getQualifier().getFormat() != ElfR32ui) error(loc, "only supported on image with format r32i or r32ui", fnCandidate.getName().c_str(), ""); } else { - if (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0) + bool isImageAtomicOnFloatAllowed = ((fnCandidate.getName().compare(0, 14, "imageAtomicAdd") == 0) || + (fnCandidate.getName().compare(0, 15, "imageAtomicLoad") == 0) || + (fnCandidate.getName().compare(0, 16, "imageAtomicStore") == 0) || + (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") == 0)); + if (imageType.getSampler().type == EbtFloat && isImageAtomicOnFloatAllowed && + (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0)) // imageAtomicExchange doesn't require GL_EXT_shader_atomic_float + requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float, fnCandidate.getName().c_str()); + if (!isImageAtomicOnFloatAllowed) error(loc, "only supported on integer images", fnCandidate.getName().c_str(), ""); else if (imageType.getQualifier().getFormat() != ElfR32f && isEsProfile()) error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), ""); @@ -2087,10 +2161,18 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan if (argp->size() > 3) { requireExtensions(loc, 1, &E_GL_KHR_memory_scope_semantics, fnCandidate.getName().c_str()); memorySemanticsCheck(loc, fnCandidate, callNode); + if ((callNode.getOp() == EOpAtomicAdd || callNode.getOp() == EOpAtomicExchange || + callNode.getOp() == EOpAtomicLoad || callNode.getOp() == EOpAtomicStore) && + (arg0->getType().isFloatingDomain())) { + requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float, fnCandidate.getName().c_str()); + } } else if (arg0->getType().getBasicType() == EbtInt64 || arg0->getType().getBasicType() == EbtUint64) { const char* const extensions[2] = { E_GL_NV_shader_atomic_int64, E_GL_EXT_shader_atomic_int64 }; requireExtensions(loc, 2, extensions, fnCandidate.getName().c_str()); + } else if ((callNode.getOp() == EOpAtomicAdd || callNode.getOp() == EOpAtomicExchange) && + (arg0->getType().isFloatingDomain())) { + requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float, fnCandidate.getName().c_str()); } break; } @@ -2172,6 +2254,28 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan memorySemanticsCheck(loc, fnCandidate, callNode); } break; + + case EOpMix: + if (profile == EEsProfile && version < 310) { + // Look for specific signatures + if ((*argp)[0]->getAsTyped()->getBasicType() != EbtFloat && + (*argp)[1]->getAsTyped()->getBasicType() != EbtFloat && + (*argp)[2]->getAsTyped()->getBasicType() == EbtBool) { + requireExtensions(loc, 1, &E_GL_EXT_shader_integer_mix, "specific signature of builtin mix"); + } + } + + if (profile != EEsProfile && version < 450) { + if ((*argp)[0]->getAsTyped()->getBasicType() != EbtFloat && + (*argp)[0]->getAsTyped()->getBasicType() != EbtDouble && + (*argp)[1]->getAsTyped()->getBasicType() != EbtFloat && + (*argp)[1]->getAsTyped()->getBasicType() != EbtDouble && + (*argp)[2]->getAsTyped()->getBasicType() == EbtBool) { + requireExtensions(loc, 1, &E_GL_EXT_shader_integer_mix, fnCandidate.getName().c_str()); + } + } + + break; #endif default: @@ -2698,7 +2802,10 @@ void TParseContext::reservedPpErrorCheck(const TSourceLoc& loc, const char* iden if (strncmp(identifier, "GL_", 3) == 0) ppError(loc, "names beginning with \"GL_\" can't be (un)defined:", op, identifier); else if (strncmp(identifier, "defined", 8) == 0) - ppError(loc, "\"defined\" can't be (un)defined:", op, identifier); + if (relaxedErrors()) + ppWarn(loc, "\"defined\" is (un)defined:", op, identifier); + else + ppError(loc, "\"defined\" can't be (un)defined:", op, identifier); else if (strstr(identifier, "__") != 0) { if (isEsProfile() && version >= 300 && (strcmp(identifier, "__LINE__") == 0 || @@ -2706,7 +2813,7 @@ void TParseContext::reservedPpErrorCheck(const TSourceLoc& loc, const char* iden strcmp(identifier, "__VERSION__") == 0)) ppError(loc, "predefined names can't be (un)defined:", op, identifier); else { - if (isEsProfile() && version < 300) + if (isEsProfile() && version < 300 && !relaxedErrors()) ppError(loc, "names containing consecutive underscores are reserved, and an error if version < 300:", op, identifier); else ppWarn(loc, "names containing consecutive underscores are reserved:", op, identifier); @@ -3083,7 +3190,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T error(loc, "constructor argument does not have a type", "constructor", ""); return true; } - if (op != EOpConstructStruct && typed->getBasicType() == EbtSampler) { + if (op != EOpConstructStruct && op != EOpConstructNonuniform && typed->getBasicType() == EbtSampler) { error(loc, "cannot convert a sampler", "constructor", ""); return true; } @@ -3128,7 +3235,7 @@ bool TParseContext::constructorTextureSamplerError(const TSourceLoc& loc, const if (function[0].type->getBasicType() != EbtSampler || ! function[0].type->getSampler().isTexture() || function[0].type->isArray()) { - error(loc, "sampler-constructor first argument must be a scalar textureXXX type", token, ""); + error(loc, "sampler-constructor first argument must be a scalar *texture* type", token, ""); return true; } // simulate the first argument's impact on the result type, so it can be compared with the encapsulated operator!=() @@ -3136,7 +3243,8 @@ bool TParseContext::constructorTextureSamplerError(const TSourceLoc& loc, const texture.setCombined(false); texture.shadow = false; if (texture != function[0].type->getSampler()) { - error(loc, "sampler-constructor first argument must match type and dimensionality of constructor type", token, ""); + error(loc, "sampler-constructor first argument must be a *texture* type" + " matching the dimensionality and sampled type of the constructor", token, ""); return true; } @@ -3146,7 +3254,7 @@ bool TParseContext::constructorTextureSamplerError(const TSourceLoc& loc, const if ( function[1].type->getBasicType() != EbtSampler || ! function[1].type->getSampler().isPureSampler() || function[1].type->isArray()) { - error(loc, "sampler-constructor second argument must be a scalar type 'sampler'", token, ""); + error(loc, "sampler-constructor second argument must be a scalar sampler or samplerShadow", token, ""); return true; } @@ -3222,14 +3330,14 @@ void TParseContext::atomicUintCheck(const TSourceLoc& loc, const TType& type, co error(loc, "atomic_uints can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str()); } -void TParseContext::accStructNVCheck(const TSourceLoc& loc, const TType& type, const TString& identifier) +void TParseContext::accStructCheck(const TSourceLoc& loc, const TType& type, const TString& identifier) { if (type.getQualifier().storage == EvqUniform) return; - if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtAccStructNV)) + if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtAccStruct)) error(loc, "non-uniform struct contains an accelerationStructureNV:", type.getBasicTypeString().c_str(), identifier.c_str()); - else if (type.getBasicType() == EbtAccStructNV && type.getQualifier().storage != EvqUniform) + else if (type.getBasicType() == EbtAccStruct && type.getQualifier().storage != EvqUniform) error(loc, "accelerationStructureNV can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str()); @@ -3327,6 +3435,11 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali !qualifier.hasBufferReference()) error(loc, "buffers can be declared only as blocks", "buffer", ""); + if (qualifier.storage != EvqVaryingIn && publicType.basicType == EbtDouble && + extensionTurnedOn(E_GL_ARB_vertex_attrib_64bit) && language == EShLangVertex && + version < 400) { + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 410, E_GL_ARB_gpu_shader_fp64, "vertex-shader `double` type"); + } if (qualifier.storage != EvqVaryingIn && qualifier.storage != EvqVaryingOut) return; @@ -3377,7 +3490,7 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali profileRequires(loc, ENoProfile, 150, nullptr, "vertex input arrays"); } if (publicType.basicType == EbtDouble) - profileRequires(loc, ~EEsProfile, 410, nullptr, "vertex-shader `double` type input"); + profileRequires(loc, ~EEsProfile, 410, E_GL_ARB_vertex_attrib_64bit, "vertex-shader `double` type input"); if (qualifier.isAuxiliary() || qualifier.isInterpolation() || qualifier.isMemory() || qualifier.invariant) error(loc, "vertex input cannot be further qualified", "", ""); break; @@ -3513,12 +3626,14 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons dst.precision = src.precision; #ifndef GLSLANG_WEB - if (!force && ((src.coherent && (dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent)) || - (src.devicecoherent && (dst.coherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent)) || - (src.queuefamilycoherent && (dst.coherent || dst.devicecoherent || dst.workgroupcoherent || dst.subgroupcoherent)) || - (src.workgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.subgroupcoherent)) || - (src.subgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent)))) { - error(loc, "only one coherent/devicecoherent/queuefamilycoherent/workgroupcoherent/subgroupcoherent qualifier allowed", GetPrecisionQualifierString(src.precision), ""); + if (!force && ((src.coherent && (dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) || + (src.devicecoherent && (dst.coherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) || + (src.queuefamilycoherent && (dst.coherent || dst.devicecoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) || + (src.workgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.subgroupcoherent || dst.shadercallcoherent)) || + (src.subgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.shadercallcoherent)) || + (src.shadercallcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent)))) { + error(loc, "only one coherent/devicecoherent/queuefamilycoherent/workgroupcoherent/subgroupcoherent/shadercallcoherent qualifier allowed", + GetPrecisionQualifierString(src.precision), ""); } #endif // Layout qualifiers @@ -3546,6 +3661,7 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons MERGE_SINGLETON(queuefamilycoherent); MERGE_SINGLETON(workgroupcoherent); MERGE_SINGLETON(subgroupcoherent); + MERGE_SINGLETON(shadercallcoherent); MERGE_SINGLETON(nonprivate); MERGE_SINGLETON(volatil); MERGE_SINGLETON(restrict); @@ -3983,7 +4099,7 @@ void TParseContext::checkRuntimeSizable(const TSourceLoc& loc, const TIntermType } // check for additional things allowed by GL_EXT_nonuniform_qualifier - if (base.getBasicType() == EbtSampler || base.getBasicType() == EbtAccStructNV || + if (base.getBasicType() == EbtSampler || base.getBasicType() == EbtAccStruct || base.getBasicType() == EbtRayQuery || (base.getBasicType() == EbtBlock && base.getType().getQualifier().isUniformOrBuffer())) requireExtensions(loc, 1, &E_GL_EXT_nonuniform_qualifier, "variable index"); else @@ -4487,6 +4603,7 @@ void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& quali type.getQualifier().queuefamilycoherent = qualifier.queuefamilycoherent; type.getQualifier().workgroupcoherent = qualifier.workgroupcoherent; type.getQualifier().subgroupcoherent = qualifier.subgroupcoherent; + type.getQualifier().shadercallcoherent = qualifier.shadercallcoherent; type.getQualifier().nonprivate = qualifier.nonprivate; type.getQualifier().readonly = qualifier.readonly; type.getQualifier().writeonly = qualifier.writeonly; @@ -4868,7 +4985,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi #ifndef GLSLANG_WEB if (id == TQualifier::getLayoutPackingString(ElpStd430)) { requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "std430"); - profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, "std430"); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_shader_storage_buffer_object, "std430"); profileRequires(loc, EEsProfile, 310, nullptr, "std430"); publicType.qualifier.layoutPacking = ElpStd430; return; @@ -5067,13 +5184,19 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi return; } } else { - if (language == EShLangRayGenNV || language == EShLangIntersectNV || - language == EShLangAnyHitNV || language == EShLangClosestHitNV || - language == EShLangMissNV || language == EShLangCallableNV) { - if (id == "shaderrecordnv") { - publicType.qualifier.layoutShaderRecordNV = true; + if (language == EShLangRayGen || language == EShLangIntersect || + language == EShLangAnyHit || language == EShLangClosestHit || + language == EShLangMiss || language == EShLangCallable) { + if (id == "shaderrecordnv" || id == "shaderrecordext") { + if (id == "shaderrecordnv") { + requireExtensions(loc, 1, &E_GL_NV_ray_tracing, "shader record NV"); + } else { + requireExtensions(loc, 1, &E_GL_EXT_ray_tracing, "shader record EXT"); + } + publicType.qualifier.layoutShaderRecord = true; return; } + } } if (language == EShLangCompute) { @@ -5088,6 +5211,12 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi } } } + + if (id == "primitive_culling") { + requireExtensions(loc, 1, &E_GL_EXT_ray_flags_primitive_culling, "primitive culling"); + publicType.shaderQualifiers.layoutPrimitiveCulling = true; + return; + } #endif error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), ""); @@ -5135,6 +5264,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi profileRequires(loc, EEsProfile, 310, nullptr, feature); } publicType.qualifier.layoutOffset = value; + publicType.qualifier.explicitOffset = true; if (nonLiteral) error(loc, "needs a literal integer", "offset", ""); return; @@ -5347,10 +5477,10 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi case EShLangFragment: if (id == "index") { - requireProfile(loc, ECompatibilityProfile | ECoreProfile, "index layout qualifier on fragment output"); + requireProfile(loc, ECompatibilityProfile | ECoreProfile | EEsProfile, "index layout qualifier on fragment output"); const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location }; profileRequires(loc, ECompatibilityProfile | ECoreProfile, 330, 2, exts, "index layout qualifier on fragment output"); - + profileRequires(loc, EEsProfile ,310, E_GL_EXT_blend_func_extended, "index layout qualifier on fragment output"); // "It is also a compile-time error if a fragment shader sets a layout index to less than 0 or greater than 1." if (value < 0 || value > 1) { value = 0; @@ -5514,8 +5644,8 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie dst.layoutViewportRelative = true; if (src.layoutSecondaryViewportRelativeOffset != -2048) dst.layoutSecondaryViewportRelativeOffset = src.layoutSecondaryViewportRelativeOffset; - if (src.layoutShaderRecordNV) - dst.layoutShaderRecordNV = true; + if (src.layoutShaderRecord) + dst.layoutShaderRecord = true; if (src.pervertexNV) dst.pervertexNV = true; #endif @@ -5583,7 +5713,7 @@ void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symb error(loc, "cannot specify on a variable declaration", "align", ""); if (qualifier.isPushConstant()) error(loc, "can only specify on a uniform block", "push_constant", ""); - if (qualifier.isShaderRecordNV()) + if (qualifier.isShaderRecord()) error(loc, "can only specify on a buffer block", "shaderRecordNV", ""); } break; @@ -5657,11 +5787,11 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) error(loc, "cannot apply to uniform or buffer block", "location", ""); break; #ifndef GLSLANG_WEB - case EvqPayloadNV: - case EvqPayloadInNV: - case EvqHitAttrNV: - case EvqCallableDataNV: - case EvqCallableDataInNV: + case EvqPayload: + case EvqPayloadIn: + case EvqHitAttr: + case EvqCallableData: + case EvqCallableDataIn: break; #endif default: @@ -5684,6 +5814,8 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) int repeated = intermediate.addXfbBufferOffset(type); if (repeated >= 0) error(loc, "overlapping offsets at", "xfb_offset", "offset %d in buffer %d", repeated, qualifier.layoutXfbBuffer); + if (type.isUnsizedArray()) + error(loc, "unsized array", "xfb_offset", "in buffer %d", qualifier.layoutXfbBuffer); // "The offset must be a multiple of the size of the first component of the first // qualified variable or block member, or a compile-time error results. Further, if applied to an aggregate @@ -5756,7 +5888,7 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) if (spvVersion.spv > 0) { if (qualifier.isUniformOrBuffer()) { if (type.getBasicType() == EbtBlock && !qualifier.isPushConstant() && - !qualifier.isShaderRecordNV() && + !qualifier.isShaderRecord() && !qualifier.hasAttachment() && !qualifier.hasBufferReference()) error(loc, "uniform/buffer blocks require layout(binding=X)", "binding", ""); @@ -5813,7 +5945,7 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) if (qualifier.hasBufferReference() && type.getBasicType() != EbtBlock) error(loc, "can only be used with a block", "buffer_reference", ""); - if (qualifier.isShaderRecordNV() && type.getBasicType() != EbtBlock) + if (qualifier.isShaderRecord() && type.getBasicType() != EbtBlock) error(loc, "can only be used with a block", "shaderRecordNV", ""); // input attachment @@ -5958,7 +6090,7 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier if (qualifier.storage != EvqBuffer) error(loc, "can only be used with buffer", "buffer_reference", ""); } - if (qualifier.isShaderRecordNV()) { + if (qualifier.isShaderRecord()) { if (qualifier.storage != EvqBuffer) error(loc, "can only be used with a buffer", "shaderRecordNV", ""); if (qualifier.hasBinding()) @@ -5967,7 +6099,7 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier error(loc, "cannot be used with shaderRecordNV", "set", ""); } - if (qualifier.storage == EvqHitAttrNV && qualifier.hasLayout()) { + if (qualifier.storage == EvqHitAttr && qualifier.hasLayout()) { error(loc, "cannot apply layout qualifiers to hitAttributeNV variable", "hitAttributeNV", ""); } } @@ -6018,6 +6150,8 @@ void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQua error(loc, message, "num_views", ""); if (shaderQualifiers.interlockOrdering != EioNone) error(loc, message, TQualifier::getInterlockOrderingString(shaderQualifiers.interlockOrdering), ""); + if (shaderQualifiers.layoutPrimitiveCulling) + error(loc, "can only be applied as standalone", "primitive_culling", ""); #endif } @@ -6079,6 +6213,15 @@ const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunct #endif const TFunction* function = nullptr; + + // debugPrintfEXT has var args and is in the symbol table as "debugPrintfEXT()", + // mangled to "debugPrintfEXT(" + if (call.getName() == "debugPrintfEXT") { + TSymbol* symbol = symbolTable.find("debugPrintfEXT(", &builtIn); + if (symbol) + return symbol->getAsFunction(); + } + bool explicitTypesEnabled = extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int8) || extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int16) || @@ -6088,7 +6231,10 @@ const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunct extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float32) || extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float64); - if (isEsProfile() || version < 120) + if (isEsProfile()) + function = (extensionTurnedOn(E_GL_EXT_shader_implicit_conversions) && version >= 310) ? + findFunction120(loc, call, builtIn) : findFunctionExact(loc, call, builtIn); + else if (version < 120) function = findFunctionExact(loc, call, builtIn); else if (version < 400) function = extensionTurnedOn(E_GL_ARB_gpu_shader_fp64) ? findFunction400(loc, call, builtIn) : findFunction120(loc, call, builtIn); @@ -6422,6 +6568,12 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden type.copyArrayInnerSizes(publicType.arraySizes); arrayOfArrayVersionCheck(loc, type.getArraySizes()); + if (initializer) { + if (type.getBasicType() == EbtRayQuery) { + error(loc, "ray queries can only be initialized by using the rayQueryInitializeEXT intrinsic:", "=", identifier.c_str()); + } + } + if (type.isCoopMat()) { intermediate.setUseVulkanMemoryModel(); intermediate.setUseStorageBuffer(); @@ -6461,7 +6613,7 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden transparentOpaqueCheck(loc, type, identifier); #ifndef GLSLANG_WEB atomicUintCheck(loc, type, identifier); - accStructNVCheck(loc, type, identifier); + accStructCheck(loc, type, identifier); checkAndResizeMeshViewDim(loc, type, /*isBlockMember*/ false); #endif if (type.getQualifier().storage == EvqConst && type.containsReference()) { @@ -7177,6 +7329,8 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T if (!node->getType().isCoopMat()) { if (type.getBasicType() != node->getType().getBasicType()) { node = intermediate.addConversion(type.getBasicType(), node); + if (node == nullptr) + return nullptr; } node = intermediate.setAggregateOperator(node, EOpConstructCooperativeMatrix, type, node->getLoc()); } else { @@ -7355,8 +7509,8 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con arraySizesCheck(memberLoc, currentBlockQualifier, memberType.getArraySizes(), nullptr, member == typeList.size() - 1); if (memberQualifier.hasOffset()) { if (spvVersion.spv == 0) { - requireProfile(memberLoc, ~EEsProfile, "offset on block member"); - profileRequires(memberLoc, ~EEsProfile, 440, E_GL_ARB_enhanced_layouts, "offset on block member"); + profileRequires(memberLoc, ~EEsProfile, 440, E_GL_ARB_enhanced_layouts, "\"offset\" on block member"); + profileRequires(memberLoc, EEsProfile, 300, E_GL_ARB_enhanced_layouts, "\"offset\" on block member"); } } @@ -7395,7 +7549,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con // Special case for "push_constant uniform", which has a default of std430, // contrary to normal uniform defaults, and can't have a default tracked for it. if ((currentBlockQualifier.isPushConstant() && !currentBlockQualifier.hasPacking()) || - (currentBlockQualifier.isShaderRecordNV() && !currentBlockQualifier.hasPacking())) + (currentBlockQualifier.isShaderRecord() && !currentBlockQualifier.hasPacking())) currentBlockQualifier.layoutPacking = ElpStd430; // Special case for "taskNV in/out", which has a default of std430, @@ -7495,6 +7649,8 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation); fixXfbOffsets(currentBlockQualifier, typeList); fixBlockUniformOffsets(currentBlockQualifier, typeList); + fixBlockUniformLayoutMatrix(currentBlockQualifier, &typeList, nullptr); + fixBlockUniformLayoutPacking(currentBlockQualifier, &typeList, nullptr); for (unsigned int member = 0; member < typeList.size(); ++member) layoutTypeCheck(typeList[member].loc, *typeList[member].type); @@ -7612,6 +7768,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con // with a particular stage. void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& qualifier) { + const char *extsrt[2] = { E_GL_NV_ray_tracing, E_GL_EXT_ray_tracing }; switch (qualifier.storage) { case EvqUniform: profileRequires(loc, EEsProfile, 300, nullptr, "uniform block"); @@ -7621,7 +7778,7 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q break; case EvqBuffer: requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "buffer block"); - profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, "buffer block"); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_shader_storage_buffer_object, "buffer block"); profileRequires(loc, EEsProfile, 310, nullptr, "buffer block"); break; case EvqVaryingIn: @@ -7650,28 +7807,28 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q } break; #ifndef GLSLANG_WEB - case EvqPayloadNV: - profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "rayPayloadNV block"); - requireStage(loc, (EShLanguageMask)(EShLangRayGenNVMask | EShLangAnyHitNVMask | EShLangClosestHitNVMask | EShLangMissNVMask), + case EvqPayload: + profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "rayPayloadNV block"); + requireStage(loc, (EShLanguageMask)(EShLangRayGenMask | EShLangAnyHitMask | EShLangClosestHitMask | EShLangMissMask), "rayPayloadNV block"); break; - case EvqPayloadInNV: - profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "rayPayloadInNV block"); - requireStage(loc, (EShLanguageMask)(EShLangAnyHitNVMask | EShLangClosestHitNVMask | EShLangMissNVMask), + case EvqPayloadIn: + profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "rayPayloadInNV block"); + requireStage(loc, (EShLanguageMask)(EShLangAnyHitMask | EShLangClosestHitMask | EShLangMissMask), "rayPayloadInNV block"); break; - case EvqHitAttrNV: - profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "hitAttributeNV block"); - requireStage(loc, (EShLanguageMask)(EShLangIntersectNVMask | EShLangAnyHitNVMask | EShLangClosestHitNVMask), "hitAttributeNV block"); + case EvqHitAttr: + profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "hitAttributeNV block"); + requireStage(loc, (EShLanguageMask)(EShLangIntersectMask | EShLangAnyHitMask | EShLangClosestHitMask), "hitAttributeNV block"); break; - case EvqCallableDataNV: - profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "callableDataNV block"); - requireStage(loc, (EShLanguageMask)(EShLangRayGenNVMask | EShLangClosestHitNVMask | EShLangMissNVMask | EShLangCallableNVMask), + case EvqCallableData: + profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "callableDataNV block"); + requireStage(loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask | EShLangMissMask | EShLangCallableMask), "callableDataNV block"); break; - case EvqCallableDataInNV: - profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "callableDataInNV block"); - requireStage(loc, (EShLanguageMask)(EShLangCallableNVMask), "callableDataInNV block"); + case EvqCallableDataIn: + profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "callableDataInNV block"); + requireStage(loc, (EShLanguageMask)(EShLangCallableMask), "callableDataInNV block"); break; #endif default: @@ -7710,8 +7867,8 @@ void TParseContext::blockQualifierCheck(const TSourceLoc& loc, const TQualifier& error(loc, "cannot use invariant qualifier on an interface block", "invariant", ""); if (qualifier.isPushConstant()) intermediate.addPushConstantCount(); - if (qualifier.isShaderRecordNV()) - intermediate.addShaderRecordNVCount(); + if (qualifier.isShaderRecord()) + intermediate.addShaderRecordCount(); if (qualifier.isTaskMemory()) intermediate.addTaskNVCount(); } @@ -7864,6 +8021,101 @@ void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typ } } +// +// Spread LayoutMatrix to uniform block member, if a uniform block member is a struct, +// we need spread LayoutMatrix to this struct member too. and keep this rule for recursive. +// +void TParseContext::fixBlockUniformLayoutMatrix(TQualifier& qualifier, TTypeList* originTypeList, + TTypeList* tmpTypeList) +{ + assert(tmpTypeList == nullptr || originTypeList->size() == tmpTypeList->size()); + for (unsigned int member = 0; member < originTypeList->size(); ++member) { + if (qualifier.layoutPacking != ElpNone) { + if (tmpTypeList == nullptr) { + if (((*originTypeList)[member].type->isMatrix() || + (*originTypeList)[member].type->getBasicType() == EbtStruct) && + (*originTypeList)[member].type->getQualifier().layoutMatrix == ElmNone) { + (*originTypeList)[member].type->getQualifier().layoutMatrix = qualifier.layoutMatrix; + } + } else { + if (((*tmpTypeList)[member].type->isMatrix() || + (*tmpTypeList)[member].type->getBasicType() == EbtStruct) && + (*tmpTypeList)[member].type->getQualifier().layoutMatrix == ElmNone) { + (*tmpTypeList)[member].type->getQualifier().layoutMatrix = qualifier.layoutMatrix; + } + } + } + + if ((*originTypeList)[member].type->getBasicType() == EbtStruct) { + TQualifier* memberQualifier = nullptr; + // block member can be declare a matrix style, so it should be update to the member's style + if ((*originTypeList)[member].type->getQualifier().layoutMatrix == ElmNone) { + memberQualifier = &qualifier; + } else { + memberQualifier = &((*originTypeList)[member].type->getQualifier()); + } + + const TType* tmpType = tmpTypeList == nullptr ? + (*originTypeList)[member].type->clone() : (*tmpTypeList)[member].type; + + fixBlockUniformLayoutMatrix(*memberQualifier, (*originTypeList)[member].type->getWritableStruct(), + tmpType->getWritableStruct()); + + const TTypeList* structure = recordStructCopy(matrixFixRecord, (*originTypeList)[member].type, tmpType); + + if (tmpTypeList == nullptr) { + (*originTypeList)[member].type->setStruct(const_cast(structure)); + } + if (tmpTypeList != nullptr) { + (*tmpTypeList)[member].type->setStruct(const_cast(structure)); + } + } + } +} + +// +// Spread LayoutPacking to block member, if a block member is a struct, we need spread LayoutPacking to +// this struct member too. and keep this rule for recursive. +// +void TParseContext::fixBlockUniformLayoutPacking(TQualifier& qualifier, TTypeList* originTypeList, + TTypeList* tmpTypeList) +{ + assert(tmpTypeList == nullptr || originTypeList->size() == tmpTypeList->size()); + for (unsigned int member = 0; member < originTypeList->size(); ++member) { + if (qualifier.layoutPacking != ElpNone) { + if (tmpTypeList == nullptr) { + if ((*originTypeList)[member].type->getQualifier().layoutPacking == ElpNone) { + (*originTypeList)[member].type->getQualifier().layoutPacking = qualifier.layoutPacking; + } + } else { + if ((*tmpTypeList)[member].type->getQualifier().layoutPacking == ElpNone) { + (*tmpTypeList)[member].type->getQualifier().layoutPacking = qualifier.layoutPacking; + } + } + } + + if ((*originTypeList)[member].type->getBasicType() == EbtStruct) { + // Deep copy the type in pool. + // Because, struct use in different block may have different layout qualifier. + // We have to new a object to distinguish between them. + const TType* tmpType = tmpTypeList == nullptr ? + (*originTypeList)[member].type->clone() : (*tmpTypeList)[member].type; + + fixBlockUniformLayoutPacking(qualifier, (*originTypeList)[member].type->getWritableStruct(), + tmpType->getWritableStruct()); + + const TTypeList* structure = recordStructCopy(packingFixRecord, (*originTypeList)[member].type, tmpType); + + if (tmpTypeList == nullptr) { + (*originTypeList)[member].type->setStruct(const_cast(structure)); + } + if (tmpTypeList != nullptr) { + (*tmpTypeList)[member].type->setStruct(const_cast(structure)); + } + } + } +} + // For an identifier that is already declared, add more qualification to it. void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qualifier, const TString& identifier) { @@ -8172,6 +8424,16 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con { checkIoArraysConsistency(loc); } + + if (publicType.shaderQualifiers.layoutPrimitiveCulling) { + if (publicType.qualifier.storage != EvqTemporary) + error(loc, "layout qualifier can not have storage qualifiers", "primitive_culling","", ""); + else { + intermediate.setLayoutPrimitiveCulling(); + } + // Exit early as further checks are not valid + return; + } #endif const TQualifier& qualifier = publicType.qualifier; @@ -8233,7 +8495,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con error(loc, "cannot declare a default, can only be used on a block", "buffer_reference", ""); if (qualifier.hasSpecConstantId()) error(loc, "cannot declare a default, can only be used on a scalar", "constant_id", ""); - if (qualifier.isShaderRecordNV()) + if (qualifier.isShaderRecord()) error(loc, "cannot declare a default, can only be used on a block", "shaderRecordNV", ""); } @@ -8322,5 +8584,43 @@ TIntermNode* TParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expre return switchNode; } +// +// When a struct used in block, and has it's own layout packing, layout matrix, +// record the origin structure of a struct to map, and Record the structure copy to the copy table, +// +const TTypeList* TParseContext::recordStructCopy(TStructRecord& record, const TType* originType, const TType* tmpType) +{ + size_t memberCount = tmpType->getStruct()->size(); + size_t originHash = 0, tmpHash = 0; + std::hash hasher; + for (size_t i = 0; i < memberCount; i++) { + size_t originMemberHash = hasher(originType->getStruct()->at(i).type->getQualifier().layoutPacking + + originType->getStruct()->at(i).type->getQualifier().layoutMatrix); + size_t tmpMemberHash = hasher(tmpType->getStruct()->at(i).type->getQualifier().layoutPacking + + tmpType->getStruct()->at(i).type->getQualifier().layoutMatrix); + originHash = hasher((originHash ^ originMemberHash) << 1); + tmpHash = hasher((tmpHash ^ tmpMemberHash) << 1); + } + const TTypeList* originStruct = originType->getStruct(); + const TTypeList* tmpStruct = tmpType->getStruct(); + if (originHash != tmpHash) { + auto fixRecords = record.find(originStruct); + if (fixRecords != record.end()) { + auto fixRecord = fixRecords->second.find(tmpHash); + if (fixRecord != fixRecords->second.end()) { + return fixRecord->second; + } else { + record[originStruct][tmpHash] = tmpStruct; + return tmpStruct; + } + } else { + record[originStruct] = std::map(); + record[originStruct][tmpHash] = tmpStruct; + return tmpStruct; + } + } + return originStruct; +} + } // end namespace glslang diff --git a/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h b/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h index 39363f1a2..0f09adaff 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h +++ b/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h @@ -68,6 +68,7 @@ class TScanContext; class TPpContext; typedef std::set TIdSetType; +typedef std::map> TStructRecord; // // Sharable code (as well as what's in TParseVersions) across @@ -83,6 +84,7 @@ public: scopeMangler("::"), symbolTable(symbolTable), statementNestingLevel(0), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0), + currentFunctionType(nullptr), postEntryPointReturn(false), contextPragma(true, false), beginInvocationInterlockCount(0), endInvocationInterlockCount(0), @@ -315,6 +317,7 @@ public: TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right); TIntermTyped* handleUnaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* childNode); TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field); + TIntermTyped* handleDotSwizzle(const TSourceLoc&, TIntermTyped* base, const TString& field); void blockMemberExtensionCheck(const TSourceLoc&, const TIntermTyped* base, int member, const TString& memberName); TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype); TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&); @@ -326,6 +329,7 @@ public: TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*); void addInputArgumentConversions(const TFunction&, TIntermNode*&) const; TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const; + TIntermTyped* addAssign(const TSourceLoc&, TOperator op, TIntermTyped* left, TIntermTyped* right); void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&); void nonOpBuiltInCheck(const TSourceLoc&, const TFunction&, TIntermAggregate&); void userFunctionCallCheck(const TSourceLoc&, TIntermAggregate&); @@ -358,7 +362,7 @@ public: void boolCheck(const TSourceLoc&, const TPublicType&); void samplerCheck(const TSourceLoc&, const TType&, const TString& identifier, TIntermTyped* initializer); void atomicUintCheck(const TSourceLoc&, const TType&, const TString& identifier); - void accStructNVCheck(const TSourceLoc & loc, const TType & type, const TString & identifier); + void accStructCheck(const TSourceLoc & loc, const TType & type, const TString & identifier); void transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier); void memberQualifierCheck(glslang::TPublicType&); void globalQualifierFixCheck(const TSourceLoc&, TQualifier&); @@ -417,12 +421,15 @@ public: void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation); void fixXfbOffsets(TQualifier&, TTypeList&); void fixBlockUniformOffsets(TQualifier&, TTypeList&); + void fixBlockUniformLayoutMatrix(TQualifier&, TTypeList*, TTypeList*); + void fixBlockUniformLayoutPacking(TQualifier&, TTypeList*, TTypeList*); void addQualifierToExisting(const TSourceLoc&, TQualifier, const TString& identifier); void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&); void invariantCheck(const TSourceLoc&, const TQualifier&); void updateStandaloneQualifierDefaults(const TSourceLoc&, const TPublicType&); void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode); TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body); + const TTypeList* recordStructCopy(TStructRecord&, const TType*, const TType*); #ifndef GLSLANG_WEB TAttributeType attributeFromName(const TString& name) const; @@ -483,6 +490,8 @@ protected: bool anyIndexLimits; TIdSetType inductiveLoopIds; TVector needsIndexLimitationChecking; + TStructRecord matrixFixRecord; + TStructRecord packingFixRecord; // // Geometry shader input arrays: diff --git a/src/libraries/glslang/glslang/MachineIndependent/Scan.cpp b/src/libraries/glslang/glslang/MachineIndependent/Scan.cpp index 1ab992e30..9260c4eae 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/Scan.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/Scan.cpp @@ -2,6 +2,8 @@ // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2013 LunarG, Inc. // Copyright (C) 2017 ARM Limited. +// Copyright (C) 2020 Google, Inc. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -187,17 +189,15 @@ bool TInputScanner::scanVersion(int& version, EProfile& profile, bool& notFirstT if (lookingInMiddle) { notFirstToken = true; // make forward progress by finishing off the current line plus extra new lines - if (peek() == '\n' || peek() == '\r') { - while (peek() == '\n' || peek() == '\r') - get(); - } else + if (peek() != '\n' && peek() != '\r') { do { c = get(); } while (c != EndOfInput && c != '\n' && c != '\r'); - while (peek() == '\n' || peek() == '\r') - get(); - if (peek() == EndOfInput) - return true; + } + while (peek() == '\n' || peek() == '\r') + get(); + if (peek() == EndOfInput) + return true; } lookingInMiddle = true; @@ -416,6 +416,7 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["queuefamilycoherent"] = QUEUEFAMILYCOHERENT; (*KeywordMap)["workgroupcoherent"] = WORKGROUPCOHERENT; (*KeywordMap)["subgroupcoherent"] = SUBGROUPCOHERENT; + (*KeywordMap)["shadercallcoherent"] = SHADERCALLCOHERENT; (*KeywordMap)["nonprivate"] = NONPRIVATE; (*KeywordMap)["restrict"] = RESTRICT; (*KeywordMap)["readonly"] = READONLY; @@ -704,11 +705,18 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["precise"] = PRECISE; (*KeywordMap)["rayPayloadNV"] = PAYLOADNV; + (*KeywordMap)["rayPayloadEXT"] = PAYLOADEXT; (*KeywordMap)["rayPayloadInNV"] = PAYLOADINNV; + (*KeywordMap)["rayPayloadInEXT"] = PAYLOADINEXT; (*KeywordMap)["hitAttributeNV"] = HITATTRNV; + (*KeywordMap)["hitAttributeEXT"] = HITATTREXT; (*KeywordMap)["callableDataNV"] = CALLDATANV; + (*KeywordMap)["callableDataEXT"] = CALLDATAEXT; (*KeywordMap)["callableDataInNV"] = CALLDATAINNV; + (*KeywordMap)["callableDataInEXT"] = CALLDATAINEXT; (*KeywordMap)["accelerationStructureNV"] = ACCSTRUCTNV; + (*KeywordMap)["accelerationStructureEXT"] = ACCSTRUCTEXT; + (*KeywordMap)["rayQueryEXT"] = RAYQUERYEXT; (*KeywordMap)["perprimitiveNV"] = PERPRIMITIVENV; (*KeywordMap)["perviewNV"] = PERVIEWNV; (*KeywordMap)["taskNV"] = PERTASKNV; @@ -843,6 +851,7 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token) parseContext.error(loc, "not supported", "::", ""); break; + case PpAtomConstString: parserToken->sType.lex.string = NewPoolTString(tokenText); return STRING_LITERAL; case PpAtomConstInt: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT; case PpAtomConstUint: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT; case PpAtomConstFloat: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT; @@ -908,7 +917,8 @@ int TScanContext::tokenizeIdentifier() case BUFFER: afterBuffer = true; if ((parseContext.isEsProfile() && parseContext.version < 310) || - (!parseContext.isEsProfile() && parseContext.version < 430)) + (!parseContext.isEsProfile() && (parseContext.version < 430 && + !parseContext.extensionTurnedOn(E_GL_ARB_shader_storage_buffer_object)))) return identifierOrType(); return keyword; @@ -1014,6 +1024,23 @@ int TScanContext::tokenizeIdentifier() parseContext.extensionTurnedOn(E_GL_NV_ray_tracing)) return keyword; return identifierOrType(); + case PAYLOADEXT: + case PAYLOADINEXT: + case HITATTREXT: + case CALLDATAEXT: + case CALLDATAINEXT: + case ACCSTRUCTEXT: + if (parseContext.symbolTable.atBuiltInLevel() || + parseContext.extensionTurnedOn(E_GL_EXT_ray_tracing) || + parseContext.extensionTurnedOn(E_GL_EXT_ray_query)) + return keyword; + return identifierOrType(); + case RAYQUERYEXT: + if (parseContext.symbolTable.atBuiltInLevel() || + (!parseContext.isEsProfile() && parseContext.version >= 460 + && parseContext.extensionTurnedOn(E_GL_EXT_ray_query))) + return keyword; + return identifierOrType(); case ATOMIC_UINT: if ((parseContext.isEsProfile() && parseContext.version >= 310) || parseContext.extensionTurnedOn(E_GL_ARB_shader_atomic_counters)) @@ -1025,6 +1052,7 @@ int TScanContext::tokenizeIdentifier() case QUEUEFAMILYCOHERENT: case WORKGROUPCOHERENT: case SUBGROUPCOHERENT: + case SHADERCALLCOHERENT: case NONPRIVATE: case RESTRICT: case READONLY: @@ -1168,8 +1196,8 @@ int TScanContext::tokenizeIdentifier() afterType = true; if (parseContext.isEsProfile() || parseContext.version < 150 || (!parseContext.symbolTable.atBuiltInLevel() && - parseContext.version < 400 && - !parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_fp64))) + (parseContext.version < 400 && !parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_fp64) && + (parseContext.version < 410 && !parseContext.extensionTurnedOn(E_GL_ARB_vertex_attrib_64bit))))) reservedWord(); return keyword; @@ -1764,7 +1792,9 @@ int TScanContext::dMat() if (!parseContext.isEsProfile() && (parseContext.version >= 400 || parseContext.symbolTable.atBuiltInLevel() || - (parseContext.version >= 150 && parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_fp64)))) + (parseContext.version >= 150 && parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_fp64)) || + (parseContext.version >= 150 && parseContext.extensionTurnedOn(E_GL_ARB_vertex_attrib_64bit) + && parseContext.language == EShLangVertex))) return keyword; if (parseContext.isForwardCompatible()) diff --git a/src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp b/src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp index 44ce1c19d..4091320cd 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp @@ -1,7 +1,7 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2013-2016 LunarG, Inc. -// Copyright (C) 2015-2018 Google, Inc. +// Copyright (C) 2015-2020 Google, Inc. // // All rights reserved. // @@ -51,9 +51,9 @@ #include "ScanContext.h" #ifdef ENABLE_HLSL -#include "../../hlsl/hlslParseHelper.h" -#include "../../hlsl/hlslParseables.h" -#include "../../hlsl/hlslScanContext.h" +#include "../HLSL/hlslParseHelper.h" +#include "../HLSL/hlslParseables.h" +#include "../HLSL/hlslScanContext.h" #endif #include "../Include/ShHandle.h" @@ -72,6 +72,9 @@ // token to print ", but none of that seems appropriate for this file. #include "preprocessor/PpTokens.h" +// Build-time generated includes +#include "../../glslang/build_info.h" + namespace { // anonymous namespace for file-local functions and symbols // Total number of successful initializers of glslang: a refcount @@ -291,6 +294,9 @@ void InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int versi #ifdef GLSLANG_WEB profile = EEsProfile; version = 310; +#elif defined(GLSLANG_ANGLE) + profile = ECoreProfile; + version = 450; #endif (*symbolTables[language]).adoptLevels(*commonTable[CommonIndex(profile, language)]); @@ -312,6 +318,9 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS #ifdef GLSLANG_WEB profile = EEsProfile; version = 310; +#elif defined(GLSLANG_ANGLE) + profile = ECoreProfile; + version = 450; #endif std::unique_ptr builtInParseables(CreateBuiltInParseables(infoSink, source)); @@ -351,7 +360,6 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS (profile == EEsProfile && version >= 310)) InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangGeometry, source, infoSink, commonTable, symbolTables); -#endif // check for compute if ((profile != EEsProfile && version >= 420) || @@ -359,19 +367,20 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCompute, source, infoSink, commonTable, symbolTables); +#ifndef GLSLANG_ANGLE // check for ray tracing stages if (profile != EEsProfile && version >= 450) { - InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangRayGenNV, source, + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangRayGen, source, infoSink, commonTable, symbolTables); - InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangIntersectNV, source, + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangIntersect, source, infoSink, commonTable, symbolTables); - InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangAnyHitNV, source, + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangAnyHit, source, infoSink, commonTable, symbolTables); - InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangClosestHitNV, source, + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangClosestHit, source, infoSink, commonTable, symbolTables); - InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMissNV, source, + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMiss, source, infoSink, commonTable, symbolTables); - InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCallableNV, source, + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCallable, source, infoSink, commonTable, symbolTables); } @@ -386,6 +395,8 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS (profile == EEsProfile && version >= 320)) InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTaskNV, source, infoSink, commonTable, symbolTables); +#endif // !GLSLANG_ANGLE +#endif // !GLSLANG_WEB return true; } @@ -487,7 +498,7 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp // Function to Print all builtins void DumpBuiltinSymbolTable(TInfoSink& infoSink, const TSymbolTable& symbolTable) { -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) infoSink.debug << "BuiltinSymbolTable {\n"; symbolTable.dump(infoSink, true); @@ -591,7 +602,7 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo break; } -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) // Correct for stage type... switch (stage) { case EShLangGeometry: @@ -623,12 +634,12 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo version = profile == EEsProfile ? 310 : 420; } break; - case EShLangRayGenNV: - case EShLangIntersectNV: - case EShLangAnyHitNV: - case EShLangClosestHitNV: - case EShLangMissNV: - case EShLangCallableNV: + case EShLangRayGen: + case EShLangIntersect: + case EShLangAnyHit: + case EShLangClosestHit: + case EShLangMiss: + case EShLangCallable: if (profile == EEsProfile || version < 460) { correct = false; infoSink.info.message(EPrefixError, "#version: ray tracing shaders require non-es profile with version 460 or above"); @@ -716,6 +727,9 @@ void TranslateEnvironment(const TEnvironment* environment, EShMessages& messages case EShClientOpenGL: spvVersion.openGl = environment->input.dialectVersion; break; + case EShClientCount: + assert(0); + break; } switch (environment->input.languageFamily) { case EShSourceNone: @@ -728,6 +742,9 @@ void TranslateEnvironment(const TEnvironment* environment, EShMessages& messages source = EShSourceHlsl; messages = static_cast(messages | EShMsgReadHlsl); break; + case EShSourceCount: + assert(0); + break; } } @@ -861,7 +878,7 @@ bool ProcessDeferred( : userInput.scanVersion(version, profile, versionNotFirstToken); bool versionNotFound = version == 0; if (forceDefaultVersionAndProfile && source == EShSourceGlsl) { -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) if (! (messages & EShMsgSuppressWarnings) && ! versionNotFound && (version != defaultVersion || profile != defaultProfile)) { compiler->infoSink.info << "Warning, (version, profile) forced to be (" @@ -884,10 +901,13 @@ bool ProcessDeferred( #ifdef GLSLANG_WEB profile = EEsProfile; version = 310; +#elif defined(GLSLANG_ANGLE) + profile = ECoreProfile; + version = 450; #endif bool versionWillBeError = (versionNotFound || (profile == EEsProfile && version >= 300 && versionNotFirst)); -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) bool warnVersionNotFirst = false; if (! versionWillBeError && versionNotFirstToken) { if (messages & EShMsgRelaxedErrors) @@ -957,7 +977,7 @@ bool ProcessDeferred( parseContext->setLimits(*resources); if (! goodVersion) parseContext->addError(); -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) if (warnVersionNotFirst) { TSourceLoc loc; loc.init(); @@ -994,7 +1014,7 @@ bool ProcessDeferred( return success; } -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) // Responsible for keeping track of the most recent source string and line in // the preprocessor and outputting newlines appropriately if the source string @@ -1217,14 +1237,16 @@ struct DoFullParse{ parseContext.infoSink.info << parseContext.getNumErrors() << " compilation errors. No code generated.\n\n"; } +#ifndef GLSLANG_ANGLE if (messages & EShMsgAST) intermediate.output(parseContext.infoSink, true); +#endif return success; } }; -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) // Take a single compilation unit, and run the preprocessor on it. // Return: True if there were no issues found in preprocessing, // False if during preprocessing any unknown version, pragmas or @@ -1678,19 +1700,29 @@ int ShGetUniformLocation(const ShHandle handle, const char* name) namespace glslang { -#include "../Include/revision.h" +Version GetVersion() +{ + Version version; + version.major = GLSLANG_VERSION_MAJOR; + version.minor = GLSLANG_VERSION_MINOR; + version.patch = GLSLANG_VERSION_PATCH; + version.flavor = GLSLANG_VERSION_FLAVOR; + return version; +} #define QUOTE(s) #s #define STR(n) QUOTE(n) const char* GetEsslVersionString() { - return "OpenGL ES GLSL 3.20 glslang Khronos. " STR(GLSLANG_MINOR_VERSION) "." STR(GLSLANG_PATCH_LEVEL); + return "OpenGL ES GLSL 3.20 glslang Khronos. " STR(GLSLANG_VERSION_MAJOR) "." STR(GLSLANG_VERSION_MINOR) "." STR( + GLSLANG_VERSION_PATCH) GLSLANG_VERSION_FLAVOR; } const char* GetGlslVersionString() { - return "4.60 glslang Khronos. " STR(GLSLANG_MINOR_VERSION) "." STR(GLSLANG_PATCH_LEVEL); + return "4.60 glslang Khronos. " STR(GLSLANG_VERSION_MAJOR) "." STR(GLSLANG_VERSION_MINOR) "." STR( + GLSLANG_VERSION_PATCH) GLSLANG_VERSION_FLAVOR; } int GetKhronosToolId() @@ -1771,6 +1803,8 @@ void TShader::setSourceEntryPoint(const char* name) sourceEntryPointName = name; } +// Log initial settings and transforms. +// See comment for class TProcesses. void TShader::addProcesses(const std::vector& p) { intermediate->addProcesses(p); @@ -1852,7 +1886,7 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion &environment); } -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) // Fill in a string with the result of preprocessing ShaderStrings // Returns true if all extensions, pragmas and version strings were valid. // @@ -1890,7 +1924,7 @@ const char* TShader::getInfoDebugLog() } TProgram::TProgram() : -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) reflection(0), #endif linked(false) @@ -1906,7 +1940,7 @@ TProgram::TProgram() : TProgram::~TProgram() { delete infoSink; -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) delete reflection; #endif @@ -1953,7 +1987,7 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages) if (stages[stage].size() == 0) return true; -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) int numEsShaders = 0, numNonEsShaders = 0; for (auto it = stages[stage].begin(); it != stages[stage].end(); ++it) { if ((*it)->intermediate->getProfile() == EEsProfile) { @@ -2007,8 +2041,10 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages) #endif intermediate[stage]->finalCheck(*infoSink, (messages & EShMsgKeepUncalled) != 0); +#ifndef GLSLANG_ANGLE if (messages & EShMsgAST) intermediate[stage]->output(*infoSink, true); +#endif return intermediate[stage]->getNumErrors() == 0; } @@ -2023,7 +2059,7 @@ const char* TProgram::getInfoDebugLog() return infoSink->debug.c_str(); } -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) // // Reflection implementation. @@ -2105,6 +2141,6 @@ bool TProgram::mapIO(TIoMapResolver* pResolver, TIoMapper* pIoMapper) return ioMapper->doMap(pResolver, *infoSink); } -#endif // GLSLANG_WEB +#endif // !GLSLANG_WEB && !GLSLANG_ANGLE } // end namespace glslang diff --git a/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.cpp b/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.cpp index 44682379f..007f22c1b 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.cpp @@ -3,6 +3,7 @@ // Copyright (C) 2012-2013 LunarG, Inc. // Copyright (C) 2017 ARM Limited. // Copyright (C) 2015-2018 Google, Inc. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -74,7 +75,8 @@ void TType::buildMangledName(TString& mangledName) const case EbtInt64: mangledName += "i64"; break; case EbtUint64: mangledName += "u64"; break; case EbtAtomicUint: mangledName += "au"; break; - case EbtAccStructNV: mangledName += "asnv"; break; + case EbtAccStruct: mangledName += "as"; break; + case EbtRayQuery: mangledName += "rq"; break; #endif case EbtSampler: switch (sampler.type) { @@ -120,7 +122,7 @@ void TType::buildMangledName(TString& mangledName) const mangledName += "-tx-struct"; char text[16]; // plenty enough space for the small integers. - snprintf(text, sizeof(text), "%d-", sampler.getStructReturnIndex()); + snprintf(text, sizeof(text), "%u-", sampler.getStructReturnIndex()); mangledName += text; } else { switch (sampler.getVectorSize()) { @@ -176,7 +178,7 @@ void TType::buildMangledName(TString& mangledName) const } } -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) // // Dump functions. diff --git a/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.h b/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.h index 40ca3da53..ec4bc3c59 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.h +++ b/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.h @@ -117,7 +117,7 @@ public: virtual int getNumExtensions() const { return extensions == nullptr ? 0 : (int)extensions->size(); } virtual const char** getExtensions() const { return extensions->data(); } -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) virtual void dump(TInfoSink& infoSink, bool complete = false) const = 0; void dumpExtensions(TInfoSink& infoSink) const; #endif @@ -196,7 +196,7 @@ public: } virtual const char** getMemberExtensions(int member) const { return (*memberExtensions)[member].data(); } -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) virtual void dump(TInfoSink& infoSink, bool complete = false) const; #endif @@ -319,7 +319,7 @@ public: virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; } virtual const TParameter& operator[](int i) const { return parameters[i]; } -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) virtual void dump(TInfoSink& infoSink, bool complete = false) const override; #endif @@ -381,7 +381,7 @@ public: virtual const char** getExtensions() const override { return anonContainer.getMemberExtensions(memberNumber); } virtual int getAnonId() const { return anonId; } -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) virtual void dump(TInfoSink& infoSink, bool complete = false) const override; #endif @@ -551,7 +551,7 @@ public: void relateToOperator(const char* name, TOperator op); void setFunctionExtensions(const char* name, int num, const char* const extensions[]); -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) void dump(TInfoSink& infoSink, bool complete = false) const; #endif TSymbolTableLevel* clone() const; @@ -854,7 +854,7 @@ public: } int getMaxSymbolId() { return uniqueId; } -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) void dump(TInfoSink& infoSink, bool complete = false) const; #endif void copyTable(const TSymbolTable& copyOf); diff --git a/src/libraries/glslang/glslang/MachineIndependent/Versions.cpp b/src/libraries/glslang/glslang/MachineIndependent/Versions.cpp index 47b07d87b..569e5391d 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/Versions.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/Versions.cpp @@ -2,7 +2,8 @@ // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2013 LunarG, Inc. // Copyright (C) 2017 ARM Limited. -// Copyright (C) 2015-2018 Google, Inc. +// Copyright (C) 2015-2020 Google, Inc. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -63,6 +64,7 @@ // checkDeprecated() // requireNotRemoved() // requireExtensions() +// extensionRequires() // // Typically, only the first two calls are needed. They go into a code path that // implements Feature F, and will log the proper error/warning messages. Parsing @@ -77,9 +79,11 @@ // const char* const XXX_extension_X = "XXX_extension_X"; // // 2) Add extension initialization to TParseVersions::initializeExtensionBehavior(), -// the first function below: +// the first function below and optionally a entry to extensionData for additional +// error checks: // // extensionBehavior[XXX_extension_X] = EBhDisable; +// (Optional) exts[] = {XXX_extension_X, EShTargetSpv_1_4} // // 3) Add any preprocessor directives etc. in the next function, TParseVersions::getPreamble(): // @@ -139,6 +143,8 @@ // set of extensions that both enable them and are necessary, given the version of the symbol // table. (There is a different symbol table for each version.) // +// 7) If the extension has additional requirements like minimum SPIR-V version required, add them +// to extensionRequires() #include "parseVersions.h" #include "localintermediate.h" @@ -154,6 +160,20 @@ namespace glslang { // void TParseVersions::initializeExtensionBehavior() { + typedef struct { + const char *const extensionName; + EShTargetLanguageVersion minSpvVersion; + } extensionData; + + const extensionData exts[] = { {E_GL_EXT_ray_tracing, EShTargetSpv_1_4} }; + + for (size_t ii = 0; ii < sizeof(exts) / sizeof(exts[0]); ii++) { + // Add only extensions which require > spv1.0 to save space in map + if (exts[ii].minSpvVersion > EShTargetSpv_1_0) { + extensionMinSpv[E_GL_EXT_ray_tracing] = exts[ii].minSpvVersion; + } + } + extensionBehavior[E_GL_OES_texture_3D] = EBhDisable; extensionBehavior[E_GL_OES_standard_derivatives] = EBhDisable; extensionBehavior[E_GL_EXT_frag_depth] = EBhDisable; @@ -197,6 +217,12 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_ARB_shader_clock] = EBhDisable; extensionBehavior[E_GL_ARB_uniform_buffer_object] = EBhDisable; extensionBehavior[E_GL_ARB_sample_shading] = EBhDisable; + extensionBehavior[E_GL_ARB_shader_bit_encoding] = EBhDisable; + extensionBehavior[E_GL_ARB_shader_image_size] = EBhDisable; + extensionBehavior[E_GL_ARB_shader_storage_buffer_object] = EBhDisable; + extensionBehavior[E_GL_ARB_shading_language_packing] = EBhDisable; + extensionBehavior[E_GL_ARB_texture_query_lod] = EBhDisable; + extensionBehavior[E_GL_ARB_vertex_attrib_64bit] = EBhDisable; extensionBehavior[E_GL_KHR_shader_subgroup_basic] = EBhDisable; extensionBehavior[E_GL_KHR_shader_subgroup_vote] = EBhDisable; @@ -222,6 +248,7 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_EXT_buffer_reference2] = EBhDisable; extensionBehavior[E_GL_EXT_buffer_reference_uvec2] = EBhDisable; extensionBehavior[E_GL_EXT_demote_to_helper_invocation] = EBhDisable; + extensionBehavior[E_GL_EXT_debug_printf] = EBhDisable; extensionBehavior[E_GL_EXT_shader_16bit_storage] = EBhDisable; extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable; @@ -290,11 +317,17 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_OES_tessellation_point_size] = EBhDisable; extensionBehavior[E_GL_OES_texture_buffer] = EBhDisable; extensionBehavior[E_GL_OES_texture_cube_map_array] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_integer_mix] = EBhDisable; // EXT extensions - extensionBehavior[E_GL_EXT_device_group] = EBhDisable; - extensionBehavior[E_GL_EXT_multiview] = EBhDisable; - extensionBehavior[E_GL_EXT_shader_realtime_clock] = EBhDisable; + extensionBehavior[E_GL_EXT_device_group] = EBhDisable; + extensionBehavior[E_GL_EXT_multiview] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_realtime_clock] = EBhDisable; + extensionBehavior[E_GL_EXT_ray_tracing] = EBhDisable; + extensionBehavior[E_GL_EXT_ray_query] = EBhDisable; + extensionBehavior[E_GL_EXT_ray_flags_primitive_culling] = EBhDisable; + extensionBehavior[E_GL_EXT_blend_func_extended] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_implicit_conversions] = EBhDisable; // OVR extensions extensionBehavior[E_GL_OVR_multiview] = EBhDisable; @@ -315,7 +348,9 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_int16] = EBhDisable; extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_int64] = EBhDisable; extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_float16] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_atomic_float] = EBhDisable; } + #endif // GLSLANG_WEB // Get code that is not part of a shared symbol table, is specific to this shader, @@ -354,6 +389,9 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_EXT_tessellation_point_size 1\n" "#define GL_EXT_texture_buffer 1\n" "#define GL_EXT_texture_cube_map_array 1\n" + "#define GL_EXT_shader_implicit_conversions 1\n" + "#define GL_EXT_shader_integer_mix 1\n" + "#define GL_EXT_blend_func_extended 1\n" // OES matching AEP "#define GL_OES_geometry_shader 1\n" @@ -403,10 +441,16 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_ARB_sparse_texture_clamp 1\n" "#define GL_ARB_shader_stencil_export 1\n" "#define GL_ARB_sample_shading 1\n" + "#define GL_ARB_shader_image_size 1\n" + "#define GL_ARB_shading_language_packing 1\n" // "#define GL_ARB_cull_distance 1\n" // present for 4.5, but need extension control over block members "#define GL_ARB_post_depth_coverage 1\n" "#define GL_ARB_fragment_shader_interlock 1\n" "#define GL_ARB_uniform_buffer_object 1\n" + "#define GL_ARB_shader_bit_encoding 1\n" + "#define GL_ARB_shader_storage_buffer_object 1\n" + "#define GL_ARB_texture_query_lod 1\n" + "#define GL_ARB_vertex_attrib_64bit 1\n" "#define GL_EXT_shader_non_constant_global_initializers 1\n" "#define GL_EXT_shader_image_load_formatted 1\n" "#define GL_EXT_post_depth_coverage 1\n" @@ -421,6 +465,7 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_EXT_buffer_reference2 1\n" "#define GL_EXT_buffer_reference_uvec2 1\n" "#define GL_EXT_demote_to_helper_invocation 1\n" + "#define GL_EXT_debug_printf 1\n" // GL_KHR_shader_subgroup "#define GL_KHR_shader_subgroup_basic 1\n" @@ -432,8 +477,11 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_KHR_shader_subgroup_clustered 1\n" "#define GL_KHR_shader_subgroup_quad 1\n" - "#define E_GL_EXT_shader_atomic_int64 1\n" - "#define E_GL_EXT_shader_realtime_clock 1\n" + "#define GL_EXT_shader_atomic_int64 1\n" + "#define GL_EXT_shader_realtime_clock 1\n" + "#define GL_EXT_ray_tracing 1\n" + "#define GL_EXT_ray_query 1\n" + "#define GL_EXT_ray_flags_primitive_culling 1\n" "#define GL_AMD_shader_ballot 1\n" "#define GL_AMD_shader_trinary_minmax 1\n" @@ -476,6 +524,8 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_EXT_shader_subgroup_extended_types_int16 1\n" "#define GL_EXT_shader_subgroup_extended_types_int64 1\n" "#define GL_EXT_shader_subgroup_extended_types_float16 1\n" + + "#define GL_EXT_shader_atomic_float 1\n" ; if (version >= 150) { @@ -547,12 +597,12 @@ const char* StageName(EShLanguage stage) case EShLangTessControl: return "tessellation control"; case EShLangTessEvaluation: return "tessellation evaluation"; case EShLangGeometry: return "geometry"; - case EShLangRayGenNV: return "ray-generation"; - case EShLangIntersectNV: return "intersection"; - case EShLangAnyHitNV: return "any-hit"; - case EShLangClosestHitNV: return "closest-hit"; - case EShLangMissNV: return "miss"; - case EShLangCallableNV: return "callable"; + case EShLangRayGen: return "ray-generation"; + case EShLangIntersect: return "intersection"; + case EShLangAnyHit: return "any-hit"; + case EShLangClosestHit: return "closest-hit"; + case EShLangMiss: return "miss"; + case EShLangCallable: return "callable"; case EShLangMeshNV: return "mesh"; case EShLangTaskNV: return "task"; #endif @@ -715,7 +765,8 @@ bool TParseVersions::checkExtensionsRequested(const TSourceLoc& loc, int numExte // Use when there are no profile/version to check, it's just an error if one of the // extensions is not present. // -void TParseVersions::requireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc) +void TParseVersions::requireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], + const char* featureDesc) { if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc)) return; @@ -734,7 +785,8 @@ void TParseVersions::requireExtensions(const TSourceLoc& loc, int numExtensions, // Use by preprocessor when there are no profile/version to check, it's just an error if one of the // extensions is not present. // -void TParseVersions::ppRequireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc) +void TParseVersions::ppRequireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], + const char* featureDesc) { if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc)) return; @@ -800,10 +852,14 @@ void TParseVersions::updateExtensionBehavior(int line, const char* extension, co error(getCurrentLoc(), "behavior not supported:", "#extension", behaviorString); return; } + bool on = behavior != EBhDisable; // check if extension is used with correct shader stage checkExtensionStage(getCurrentLoc(), extension); + // check if extension has additional requirements + extensionRequires(getCurrentLoc(), extension ,behaviorString); + // update the requested extension updateExtensionBehavior(extension, behavior); @@ -866,6 +922,32 @@ void TParseVersions::updateExtensionBehavior(int line, const char* extension, co updateExtensionBehavior(line, "GL_EXT_shader_explicit_arithmetic_types_int64", behaviorString); else if (strcmp(extension, "GL_EXT_shader_subgroup_extended_types_float16") == 0) updateExtensionBehavior(line, "GL_EXT_shader_explicit_arithmetic_types_float16", behaviorString); + + // see if we need to update the numeric features + else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types") == 0) + intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types, on); + else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types_int8") == 0) + intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types_int8, on); + else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types_int16") == 0) + intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types_int16, on); + else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types_int32") == 0) + intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types_int32, on); + else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types_int64") == 0) + intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types_int64, on); + else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types_float16") == 0) + intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types_float16, on); + else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types_float32") == 0) + intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types_float32, on); + else if (strcmp(extension, "GL_EXT_shader_explicit_arithmetic_types_float64") == 0) + intermediate.updateNumericFeature(TNumericFeatures::shader_explicit_arithmetic_types_float64, on); + else if (strcmp(extension, "GL_EXT_shader_implicit_conversions") == 0) + intermediate.updateNumericFeature(TNumericFeatures::shader_implicit_conversions, on); + else if (strcmp(extension, "GL_ARB_gpu_shader_fp64") == 0) + intermediate.updateNumericFeature(TNumericFeatures::gpu_shader_fp64, on); + else if (strcmp(extension, "GL_AMD_gpu_shader_int16") == 0) + intermediate.updateNumericFeature(TNumericFeatures::gpu_shader_int16, on); + else if (strcmp(extension, "GL_AMD_gpu_shader_half_float") == 0) + intermediate.updateNumericFeature(TNumericFeatures::gpu_shader_half_float, on); } void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBehavior behavior) @@ -901,7 +983,7 @@ void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBe } else { if (iter->second == EBhDisablePartial) warn(getCurrentLoc(), "extension is only partially supported:", "#extension", extension); - if (behavior == EBhEnable || behavior == EBhRequire) + if (behavior != EBhDisable) intermediate.addRequestedExtension(extension); iter->second = behavior; } @@ -920,6 +1002,24 @@ void TParseVersions::checkExtensionStage(const TSourceLoc& loc, const char * con } } +// Check if extension has additional requirements +void TParseVersions::extensionRequires(const TSourceLoc &loc, const char * const extension, const char *behaviorString) +{ + bool isEnabled = false; + if (!strcmp("require", behaviorString)) + isEnabled = true; + else if (!strcmp("enable", behaviorString)) + isEnabled = true; + + if (isEnabled) { + unsigned int minSpvVersion = 0; + auto iter = extensionMinSpv.find(TString(extension)); + if (iter != extensionMinSpv.end()) + minSpvVersion = iter->second; + requireSpv(loc, extension, minSpvVersion); + } +} + // Call for any operation needing full GLSL integer data-type support. void TParseVersions::fullIntegerCheck(const TSourceLoc& loc, const char* op) { @@ -930,8 +1030,13 @@ void TParseVersions::fullIntegerCheck(const TSourceLoc& loc, const char* op) // Call for any operation needing GLSL double data-type support. void TParseVersions::doubleCheck(const TSourceLoc& loc, const char* op) { + //requireProfile(loc, ECoreProfile | ECompatibilityProfile, op); - profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, E_GL_ARB_gpu_shader_fp64, op); + if (language == EShLangVertex) { + const char* const f64_Extensions[] = {E_GL_ARB_gpu_shader_fp64, E_GL_ARB_vertex_attrib_64bit}; + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, 2, f64_Extensions, op); + } else + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, E_GL_ARB_gpu_shader_fp64, op); } // Call for any operation needing GLSL float16 data-type support. @@ -1172,5 +1277,12 @@ void TParseVersions::requireSpv(const TSourceLoc& loc, const char* op) error(loc, "only allowed when generating SPIR-V", op, ""); #endif } +void TParseVersions::requireSpv(const TSourceLoc& loc, const char *op, unsigned int version) +{ +#ifndef GLSLANG_WEB + if (spvVersion.spv < version) + error(loc, "not supported for current targeted SPIR-V version", op, ""); +#endif +} } // end namespace glslang diff --git a/src/libraries/glslang/glslang/MachineIndependent/Versions.h b/src/libraries/glslang/glslang/MachineIndependent/Versions.h index c17260f06..217fc2b48 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/Versions.h +++ b/src/libraries/glslang/glslang/MachineIndependent/Versions.h @@ -3,6 +3,7 @@ // Copyright (C) 2012-2013 LunarG, Inc. // Copyright (C) 2017 ARM Limited. // Copyright (C) 2015-2018 Google, Inc. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -35,9 +36,12 @@ // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // + #ifndef _VERSIONS_INCLUDED_ #define _VERSIONS_INCLUDED_ +#define LAST_ELEMENT_MARKER(x) x + // // Help manage multiple profiles, versions, extensions etc. // @@ -49,12 +53,13 @@ // Don't maintain an ordinal set of enums (0,1,2,3...) to avoid all possible // defects from mixing the two different forms. // -typedef enum { +typedef enum : unsigned { EBadProfile = 0, ENoProfile = (1 << 0), // only for desktop, before profiles showed up ECoreProfile = (1 << 1), ECompatibilityProfile = (1 << 2), - EEsProfile = (1 << 3) + EEsProfile = (1 << 3), + LAST_ELEMENT_MARKER(EProfileCount), } EProfile; namespace glslang { @@ -149,6 +154,12 @@ const char* const E_GL_ARB_fragment_shader_interlock = "GL_ARB_fragment_shade const char* const E_GL_ARB_shader_clock = "GL_ARB_shader_clock"; const char* const E_GL_ARB_uniform_buffer_object = "GL_ARB_uniform_buffer_object"; const char* const E_GL_ARB_sample_shading = "GL_ARB_sample_shading"; +const char* const E_GL_ARB_shader_bit_encoding = "GL_ARB_shader_bit_encoding"; +const char* const E_GL_ARB_shader_image_size = "GL_ARB_shader_image_size"; +const char* const E_GL_ARB_shader_storage_buffer_object = "GL_ARB_shader_storage_buffer_object"; +const char* const E_GL_ARB_shading_language_packing = "GL_ARB_shading_language_packing"; +const char* const E_GL_ARB_texture_query_lod = "GL_ARB_texture_query_lod"; +const char* const E_GL_ARB_vertex_attrib_64bit = "GL_ARB_vertex_attrib_64bit"; const char* const E_GL_KHR_shader_subgroup_basic = "GL_KHR_shader_subgroup_basic"; const char* const E_GL_KHR_shader_subgroup_vote = "GL_KHR_shader_subgroup_vote"; @@ -183,6 +194,12 @@ const char* const E_GL_EXT_buffer_reference2 = "GL_EXT_buffer_ref const char* const E_GL_EXT_buffer_reference_uvec2 = "GL_EXT_buffer_reference_uvec2"; const char* const E_GL_EXT_demote_to_helper_invocation = "GL_EXT_demote_to_helper_invocation"; const char* const E_GL_EXT_shader_realtime_clock = "GL_EXT_shader_realtime_clock"; +const char* const E_GL_EXT_debug_printf = "GL_EXT_debug_printf"; +const char* const E_GL_EXT_ray_tracing = "GL_EXT_ray_tracing"; +const char* const E_GL_EXT_ray_query = "GL_EXT_ray_query"; +const char* const E_GL_EXT_ray_flags_primitive_culling = "GL_EXT_ray_flags_primitive_culling"; +const char* const E_GL_EXT_blend_func_extended = "GL_EXT_blend_func_extended"; +const char* const E_GL_EXT_shader_implicit_conversions = "GL_EXT_shader_implicit_conversions"; // Arrays of extensions for the above viewportEXTs duplications @@ -254,6 +271,7 @@ const char* const E_GL_EXT_tessellation_shader = "GL_EXT_tessel const char* const E_GL_EXT_tessellation_point_size = "GL_EXT_tessellation_point_size"; const char* const E_GL_EXT_texture_buffer = "GL_EXT_texture_buffer"; const char* const E_GL_EXT_texture_cube_map_array = "GL_EXT_texture_cube_map_array"; +const char* const E_GL_EXT_shader_integer_mix = "GL_EXT_shader_integer_mix"; // OES matching AEP const char* const E_GL_OES_geometry_shader = "GL_OES_geometry_shader"; @@ -281,6 +299,8 @@ const char* const E_GL_EXT_shader_subgroup_extended_types_int16 = "GL_EXT_shad const char* const E_GL_EXT_shader_subgroup_extended_types_int64 = "GL_EXT_shader_subgroup_extended_types_int64"; const char* const E_GL_EXT_shader_subgroup_extended_types_float16 = "GL_EXT_shader_subgroup_extended_types_float16"; +const char* const E_GL_EXT_shader_atomic_float = "GL_EXT_shader_atomic_float"; + // Arrays of extensions for the above AEP duplications const char* const AEP_geometry_shader[] = { E_GL_EXT_geometry_shader, E_GL_OES_geometry_shader }; diff --git a/src/libraries/glslang/glslang/MachineIndependent/gl_types.h b/src/libraries/glslang/glslang/MachineIndependent/gl_types.h index b6f613bce..b9372d4bb 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/gl_types.h +++ b/src/libraries/glslang/glslang/MachineIndependent/gl_types.h @@ -52,6 +52,14 @@ #define GL_UNSIGNED_INT64_VEC2_ARB 0x8FE5 #define GL_UNSIGNED_INT64_VEC3_ARB 0x8FE6 #define GL_UNSIGNED_INT64_VEC4_ARB 0x8FE7 +#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1 +#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2 +#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3 + +#define GL_INT16_NV 0x8FE4 +#define GL_INT16_VEC2_NV 0x8FE5 +#define GL_INT16_VEC3_NV 0x8FE6 +#define GL_INT16_VEC4_NV 0x8FE7 #define GL_BOOL 0x8B56 #define GL_BOOL_VEC2 0x8B57 diff --git a/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp b/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp index 2a47faada..ac3579779 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp @@ -62,7 +62,7 @@ /* Copy the first part of user declarations. */ -#line 68 "MachineIndependent/glslang.y" /* yacc.c:339 */ +#line 69 "MachineIndependent/glslang.y" /* yacc.c:339 */ /* Based on: @@ -281,256 +281,265 @@ extern int yydebug; F64MAT4X4 = 413, ATOMIC_UINT = 414, ACCSTRUCTNV = 415, - FCOOPMATNV = 416, - ICOOPMATNV = 417, - UCOOPMATNV = 418, - SAMPLERCUBEARRAY = 419, - SAMPLERCUBEARRAYSHADOW = 420, - ISAMPLERCUBEARRAY = 421, - USAMPLERCUBEARRAY = 422, - SAMPLER1D = 423, - SAMPLER1DARRAY = 424, - SAMPLER1DARRAYSHADOW = 425, - ISAMPLER1D = 426, - SAMPLER1DSHADOW = 427, - SAMPLER2DRECT = 428, - SAMPLER2DRECTSHADOW = 429, - ISAMPLER2DRECT = 430, - USAMPLER2DRECT = 431, - SAMPLERBUFFER = 432, - ISAMPLERBUFFER = 433, - USAMPLERBUFFER = 434, - SAMPLER2DMS = 435, - ISAMPLER2DMS = 436, - USAMPLER2DMS = 437, - SAMPLER2DMSARRAY = 438, - ISAMPLER2DMSARRAY = 439, - USAMPLER2DMSARRAY = 440, - SAMPLEREXTERNALOES = 441, - SAMPLEREXTERNAL2DY2YEXT = 442, - ISAMPLER1DARRAY = 443, - USAMPLER1D = 444, - USAMPLER1DARRAY = 445, - F16SAMPLER1D = 446, - F16SAMPLER2D = 447, - F16SAMPLER3D = 448, - F16SAMPLER2DRECT = 449, - F16SAMPLERCUBE = 450, - F16SAMPLER1DARRAY = 451, - F16SAMPLER2DARRAY = 452, - F16SAMPLERCUBEARRAY = 453, - F16SAMPLERBUFFER = 454, - F16SAMPLER2DMS = 455, - F16SAMPLER2DMSARRAY = 456, - F16SAMPLER1DSHADOW = 457, - F16SAMPLER2DSHADOW = 458, - F16SAMPLER1DARRAYSHADOW = 459, - F16SAMPLER2DARRAYSHADOW = 460, - F16SAMPLER2DRECTSHADOW = 461, - F16SAMPLERCUBESHADOW = 462, - F16SAMPLERCUBEARRAYSHADOW = 463, - IMAGE1D = 464, - IIMAGE1D = 465, - UIMAGE1D = 466, - IMAGE2D = 467, - IIMAGE2D = 468, - UIMAGE2D = 469, - IMAGE3D = 470, - IIMAGE3D = 471, - UIMAGE3D = 472, - IMAGE2DRECT = 473, - IIMAGE2DRECT = 474, - UIMAGE2DRECT = 475, - IMAGECUBE = 476, - IIMAGECUBE = 477, - UIMAGECUBE = 478, - IMAGEBUFFER = 479, - IIMAGEBUFFER = 480, - UIMAGEBUFFER = 481, - IMAGE1DARRAY = 482, - IIMAGE1DARRAY = 483, - UIMAGE1DARRAY = 484, - IMAGE2DARRAY = 485, - IIMAGE2DARRAY = 486, - UIMAGE2DARRAY = 487, - IMAGECUBEARRAY = 488, - IIMAGECUBEARRAY = 489, - UIMAGECUBEARRAY = 490, - IMAGE2DMS = 491, - IIMAGE2DMS = 492, - UIMAGE2DMS = 493, - IMAGE2DMSARRAY = 494, - IIMAGE2DMSARRAY = 495, - UIMAGE2DMSARRAY = 496, - F16IMAGE1D = 497, - F16IMAGE2D = 498, - F16IMAGE3D = 499, - F16IMAGE2DRECT = 500, - F16IMAGECUBE = 501, - F16IMAGE1DARRAY = 502, - F16IMAGE2DARRAY = 503, - F16IMAGECUBEARRAY = 504, - F16IMAGEBUFFER = 505, - F16IMAGE2DMS = 506, - F16IMAGE2DMSARRAY = 507, - TEXTURECUBEARRAY = 508, - ITEXTURECUBEARRAY = 509, - UTEXTURECUBEARRAY = 510, - TEXTURE1D = 511, - ITEXTURE1D = 512, - UTEXTURE1D = 513, - TEXTURE1DARRAY = 514, - ITEXTURE1DARRAY = 515, - UTEXTURE1DARRAY = 516, - TEXTURE2DRECT = 517, - ITEXTURE2DRECT = 518, - UTEXTURE2DRECT = 519, - TEXTUREBUFFER = 520, - ITEXTUREBUFFER = 521, - UTEXTUREBUFFER = 522, - TEXTURE2DMS = 523, - ITEXTURE2DMS = 524, - UTEXTURE2DMS = 525, - TEXTURE2DMSARRAY = 526, - ITEXTURE2DMSARRAY = 527, - UTEXTURE2DMSARRAY = 528, - F16TEXTURE1D = 529, - F16TEXTURE2D = 530, - F16TEXTURE3D = 531, - F16TEXTURE2DRECT = 532, - F16TEXTURECUBE = 533, - F16TEXTURE1DARRAY = 534, - F16TEXTURE2DARRAY = 535, - F16TEXTURECUBEARRAY = 536, - F16TEXTUREBUFFER = 537, - F16TEXTURE2DMS = 538, - F16TEXTURE2DMSARRAY = 539, - SUBPASSINPUT = 540, - SUBPASSINPUTMS = 541, - ISUBPASSINPUT = 542, - ISUBPASSINPUTMS = 543, - USUBPASSINPUT = 544, - USUBPASSINPUTMS = 545, - F16SUBPASSINPUT = 546, - F16SUBPASSINPUTMS = 547, - LEFT_OP = 548, - RIGHT_OP = 549, - INC_OP = 550, - DEC_OP = 551, - LE_OP = 552, - GE_OP = 553, - EQ_OP = 554, - NE_OP = 555, - AND_OP = 556, - OR_OP = 557, - XOR_OP = 558, - MUL_ASSIGN = 559, - DIV_ASSIGN = 560, - ADD_ASSIGN = 561, - MOD_ASSIGN = 562, - LEFT_ASSIGN = 563, - RIGHT_ASSIGN = 564, - AND_ASSIGN = 565, - XOR_ASSIGN = 566, - OR_ASSIGN = 567, - SUB_ASSIGN = 568, - LEFT_PAREN = 569, - RIGHT_PAREN = 570, - LEFT_BRACKET = 571, - RIGHT_BRACKET = 572, - LEFT_BRACE = 573, - RIGHT_BRACE = 574, - DOT = 575, - COMMA = 576, - COLON = 577, - EQUAL = 578, - SEMICOLON = 579, - BANG = 580, - DASH = 581, - TILDE = 582, - PLUS = 583, - STAR = 584, - SLASH = 585, - PERCENT = 586, - LEFT_ANGLE = 587, - RIGHT_ANGLE = 588, - VERTICAL_BAR = 589, - CARET = 590, - AMPERSAND = 591, - QUESTION = 592, - INVARIANT = 593, - HIGH_PRECISION = 594, - MEDIUM_PRECISION = 595, - LOW_PRECISION = 596, - PRECISION = 597, - PACKED = 598, - RESOURCE = 599, - SUPERP = 600, - FLOATCONSTANT = 601, - INTCONSTANT = 602, - UINTCONSTANT = 603, - BOOLCONSTANT = 604, - IDENTIFIER = 605, - TYPE_NAME = 606, - CENTROID = 607, - IN = 608, - OUT = 609, - INOUT = 610, - STRUCT = 611, - VOID = 612, - WHILE = 613, - BREAK = 614, - CONTINUE = 615, - DO = 616, - ELSE = 617, - FOR = 618, - IF = 619, - DISCARD = 620, - RETURN = 621, - SWITCH = 622, - CASE = 623, - DEFAULT = 624, - UNIFORM = 625, - SHARED = 626, - BUFFER = 627, - FLAT = 628, - SMOOTH = 629, - LAYOUT = 630, - DOUBLECONSTANT = 631, - INT16CONSTANT = 632, - UINT16CONSTANT = 633, - FLOAT16CONSTANT = 634, - INT32CONSTANT = 635, - UINT32CONSTANT = 636, - INT64CONSTANT = 637, - UINT64CONSTANT = 638, - SUBROUTINE = 639, - DEMOTE = 640, - PAYLOADNV = 641, - PAYLOADINNV = 642, - HITATTRNV = 643, - CALLDATANV = 644, - CALLDATAINNV = 645, - PATCH = 646, - SAMPLE = 647, - NONUNIFORM = 648, - COHERENT = 649, - VOLATILE = 650, - RESTRICT = 651, - READONLY = 652, - WRITEONLY = 653, - DEVICECOHERENT = 654, - QUEUEFAMILYCOHERENT = 655, - WORKGROUPCOHERENT = 656, - SUBGROUPCOHERENT = 657, - NONPRIVATE = 658, - NOPERSPECTIVE = 659, - EXPLICITINTERPAMD = 660, - PERVERTEXNV = 661, - PERPRIMITIVENV = 662, - PERVIEWNV = 663, - PERTASKNV = 664, - PRECISE = 665 + ACCSTRUCTEXT = 416, + RAYQUERYEXT = 417, + FCOOPMATNV = 418, + ICOOPMATNV = 419, + UCOOPMATNV = 420, + SAMPLERCUBEARRAY = 421, + SAMPLERCUBEARRAYSHADOW = 422, + ISAMPLERCUBEARRAY = 423, + USAMPLERCUBEARRAY = 424, + SAMPLER1D = 425, + SAMPLER1DARRAY = 426, + SAMPLER1DARRAYSHADOW = 427, + ISAMPLER1D = 428, + SAMPLER1DSHADOW = 429, + SAMPLER2DRECT = 430, + SAMPLER2DRECTSHADOW = 431, + ISAMPLER2DRECT = 432, + USAMPLER2DRECT = 433, + SAMPLERBUFFER = 434, + ISAMPLERBUFFER = 435, + USAMPLERBUFFER = 436, + SAMPLER2DMS = 437, + ISAMPLER2DMS = 438, + USAMPLER2DMS = 439, + SAMPLER2DMSARRAY = 440, + ISAMPLER2DMSARRAY = 441, + USAMPLER2DMSARRAY = 442, + SAMPLEREXTERNALOES = 443, + SAMPLEREXTERNAL2DY2YEXT = 444, + ISAMPLER1DARRAY = 445, + USAMPLER1D = 446, + USAMPLER1DARRAY = 447, + F16SAMPLER1D = 448, + F16SAMPLER2D = 449, + F16SAMPLER3D = 450, + F16SAMPLER2DRECT = 451, + F16SAMPLERCUBE = 452, + F16SAMPLER1DARRAY = 453, + F16SAMPLER2DARRAY = 454, + F16SAMPLERCUBEARRAY = 455, + F16SAMPLERBUFFER = 456, + F16SAMPLER2DMS = 457, + F16SAMPLER2DMSARRAY = 458, + F16SAMPLER1DSHADOW = 459, + F16SAMPLER2DSHADOW = 460, + F16SAMPLER1DARRAYSHADOW = 461, + F16SAMPLER2DARRAYSHADOW = 462, + F16SAMPLER2DRECTSHADOW = 463, + F16SAMPLERCUBESHADOW = 464, + F16SAMPLERCUBEARRAYSHADOW = 465, + IMAGE1D = 466, + IIMAGE1D = 467, + UIMAGE1D = 468, + IMAGE2D = 469, + IIMAGE2D = 470, + UIMAGE2D = 471, + IMAGE3D = 472, + IIMAGE3D = 473, + UIMAGE3D = 474, + IMAGE2DRECT = 475, + IIMAGE2DRECT = 476, + UIMAGE2DRECT = 477, + IMAGECUBE = 478, + IIMAGECUBE = 479, + UIMAGECUBE = 480, + IMAGEBUFFER = 481, + IIMAGEBUFFER = 482, + UIMAGEBUFFER = 483, + IMAGE1DARRAY = 484, + IIMAGE1DARRAY = 485, + UIMAGE1DARRAY = 486, + IMAGE2DARRAY = 487, + IIMAGE2DARRAY = 488, + UIMAGE2DARRAY = 489, + IMAGECUBEARRAY = 490, + IIMAGECUBEARRAY = 491, + UIMAGECUBEARRAY = 492, + IMAGE2DMS = 493, + IIMAGE2DMS = 494, + UIMAGE2DMS = 495, + IMAGE2DMSARRAY = 496, + IIMAGE2DMSARRAY = 497, + UIMAGE2DMSARRAY = 498, + F16IMAGE1D = 499, + F16IMAGE2D = 500, + F16IMAGE3D = 501, + F16IMAGE2DRECT = 502, + F16IMAGECUBE = 503, + F16IMAGE1DARRAY = 504, + F16IMAGE2DARRAY = 505, + F16IMAGECUBEARRAY = 506, + F16IMAGEBUFFER = 507, + F16IMAGE2DMS = 508, + F16IMAGE2DMSARRAY = 509, + TEXTURECUBEARRAY = 510, + ITEXTURECUBEARRAY = 511, + UTEXTURECUBEARRAY = 512, + TEXTURE1D = 513, + ITEXTURE1D = 514, + UTEXTURE1D = 515, + TEXTURE1DARRAY = 516, + ITEXTURE1DARRAY = 517, + UTEXTURE1DARRAY = 518, + TEXTURE2DRECT = 519, + ITEXTURE2DRECT = 520, + UTEXTURE2DRECT = 521, + TEXTUREBUFFER = 522, + ITEXTUREBUFFER = 523, + UTEXTUREBUFFER = 524, + TEXTURE2DMS = 525, + ITEXTURE2DMS = 526, + UTEXTURE2DMS = 527, + TEXTURE2DMSARRAY = 528, + ITEXTURE2DMSARRAY = 529, + UTEXTURE2DMSARRAY = 530, + F16TEXTURE1D = 531, + F16TEXTURE2D = 532, + F16TEXTURE3D = 533, + F16TEXTURE2DRECT = 534, + F16TEXTURECUBE = 535, + F16TEXTURE1DARRAY = 536, + F16TEXTURE2DARRAY = 537, + F16TEXTURECUBEARRAY = 538, + F16TEXTUREBUFFER = 539, + F16TEXTURE2DMS = 540, + F16TEXTURE2DMSARRAY = 541, + SUBPASSINPUT = 542, + SUBPASSINPUTMS = 543, + ISUBPASSINPUT = 544, + ISUBPASSINPUTMS = 545, + USUBPASSINPUT = 546, + USUBPASSINPUTMS = 547, + F16SUBPASSINPUT = 548, + F16SUBPASSINPUTMS = 549, + LEFT_OP = 550, + RIGHT_OP = 551, + INC_OP = 552, + DEC_OP = 553, + LE_OP = 554, + GE_OP = 555, + EQ_OP = 556, + NE_OP = 557, + AND_OP = 558, + OR_OP = 559, + XOR_OP = 560, + MUL_ASSIGN = 561, + DIV_ASSIGN = 562, + ADD_ASSIGN = 563, + MOD_ASSIGN = 564, + LEFT_ASSIGN = 565, + RIGHT_ASSIGN = 566, + AND_ASSIGN = 567, + XOR_ASSIGN = 568, + OR_ASSIGN = 569, + SUB_ASSIGN = 570, + STRING_LITERAL = 571, + LEFT_PAREN = 572, + RIGHT_PAREN = 573, + LEFT_BRACKET = 574, + RIGHT_BRACKET = 575, + LEFT_BRACE = 576, + RIGHT_BRACE = 577, + DOT = 578, + COMMA = 579, + COLON = 580, + EQUAL = 581, + SEMICOLON = 582, + BANG = 583, + DASH = 584, + TILDE = 585, + PLUS = 586, + STAR = 587, + SLASH = 588, + PERCENT = 589, + LEFT_ANGLE = 590, + RIGHT_ANGLE = 591, + VERTICAL_BAR = 592, + CARET = 593, + AMPERSAND = 594, + QUESTION = 595, + INVARIANT = 596, + HIGH_PRECISION = 597, + MEDIUM_PRECISION = 598, + LOW_PRECISION = 599, + PRECISION = 600, + PACKED = 601, + RESOURCE = 602, + SUPERP = 603, + FLOATCONSTANT = 604, + INTCONSTANT = 605, + UINTCONSTANT = 606, + BOOLCONSTANT = 607, + IDENTIFIER = 608, + TYPE_NAME = 609, + CENTROID = 610, + IN = 611, + OUT = 612, + INOUT = 613, + STRUCT = 614, + VOID = 615, + WHILE = 616, + BREAK = 617, + CONTINUE = 618, + DO = 619, + ELSE = 620, + FOR = 621, + IF = 622, + DISCARD = 623, + RETURN = 624, + SWITCH = 625, + CASE = 626, + DEFAULT = 627, + UNIFORM = 628, + SHARED = 629, + BUFFER = 630, + FLAT = 631, + SMOOTH = 632, + LAYOUT = 633, + DOUBLECONSTANT = 634, + INT16CONSTANT = 635, + UINT16CONSTANT = 636, + FLOAT16CONSTANT = 637, + INT32CONSTANT = 638, + UINT32CONSTANT = 639, + INT64CONSTANT = 640, + UINT64CONSTANT = 641, + SUBROUTINE = 642, + DEMOTE = 643, + PAYLOADNV = 644, + PAYLOADINNV = 645, + HITATTRNV = 646, + CALLDATANV = 647, + CALLDATAINNV = 648, + PAYLOADEXT = 649, + PAYLOADINEXT = 650, + HITATTREXT = 651, + CALLDATAEXT = 652, + CALLDATAINEXT = 653, + PATCH = 654, + SAMPLE = 655, + NONUNIFORM = 656, + COHERENT = 657, + VOLATILE = 658, + RESTRICT = 659, + READONLY = 660, + WRITEONLY = 661, + DEVICECOHERENT = 662, + QUEUEFAMILYCOHERENT = 663, + WORKGROUPCOHERENT = 664, + SUBGROUPCOHERENT = 665, + NONPRIVATE = 666, + SHADERCALLCOHERENT = 667, + NOPERSPECTIVE = 668, + EXPLICITINTERPAMD = 669, + PERVERTEXNV = 670, + PERPRIMITIVENV = 671, + PERVIEWNV = 672, + PERTASKNV = 673, + PRECISE = 674 }; #endif @@ -539,7 +548,7 @@ extern int yydebug; union YYSTYPE { -#line 96 "MachineIndependent/glslang.y" /* yacc.c:355 */ +#line 97 "MachineIndependent/glslang.y" /* yacc.c:355 */ struct { glslang::TSourceLoc loc; @@ -575,7 +584,7 @@ union YYSTYPE glslang::TArraySizes* typeParameters; } interm; -#line 579 "MachineIndependent/glslang_tab.cpp" /* yacc.c:355 */ +#line 588 "MachineIndependent/glslang_tab.cpp" /* yacc.c:355 */ }; typedef union YYSTYPE YYSTYPE; @@ -590,7 +599,7 @@ int yyparse (glslang::TParseContext* pParseContext); #endif /* !YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED */ /* Copy the second part of user declarations. */ -#line 132 "MachineIndependent/glslang.y" /* yacc.c:358 */ +#line 133 "MachineIndependent/glslang.y" /* yacc.c:358 */ /* windows only pragma */ @@ -606,7 +615,7 @@ int yyparse (glslang::TParseContext* pParseContext); extern int yylex(YYSTYPE*, TParseContext&); -#line 610 "MachineIndependent/glslang_tab.cpp" /* yacc.c:358 */ +#line 619 "MachineIndependent/glslang_tab.cpp" /* yacc.c:358 */ #ifdef short # undef short @@ -846,23 +855,23 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 386 +#define YYFINAL 394 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 9369 +#define YYLAST 9550 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 411 +#define YYNTOKENS 420 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 111 /* YYNRULES -- Number of rules. */ -#define YYNRULES 582 +#define YYNRULES 591 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 727 +#define YYNSTATES 736 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 665 +#define YYMAXUTOK 674 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -937,72 +946,74 @@ static const yytype_uint16 yytranslate[] = 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410 + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 415, 416, 417, 418, 419 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 352, 352, 358, 361, 366, 369, 372, 376, 380, - 384, 388, 392, 396, 400, 404, 408, 416, 419, 422, - 425, 428, 433, 441, 448, 455, 461, 465, 472, 475, - 481, 488, 498, 506, 511, 539, 548, 554, 558, 562, - 582, 583, 584, 585, 591, 592, 597, 602, 611, 612, - 617, 625, 626, 632, 641, 642, 647, 652, 657, 665, - 666, 675, 687, 688, 697, 698, 707, 708, 717, 718, - 726, 727, 735, 736, 744, 745, 745, 763, 764, 780, - 784, 788, 792, 797, 801, 805, 809, 813, 817, 821, - 828, 831, 842, 849, 854, 859, 866, 870, 874, 878, - 883, 888, 897, 897, 908, 912, 919, 926, 929, 936, - 944, 964, 987, 1002, 1027, 1038, 1048, 1058, 1068, 1077, - 1080, 1084, 1088, 1093, 1101, 1108, 1113, 1118, 1123, 1132, - 1142, 1169, 1178, 1185, 1193, 1200, 1207, 1215, 1225, 1232, - 1243, 1249, 1252, 1259, 1263, 1267, 1276, 1286, 1289, 1300, - 1303, 1306, 1310, 1314, 1319, 1323, 1330, 1334, 1339, 1345, - 1351, 1358, 1363, 1371, 1377, 1389, 1403, 1409, 1414, 1422, - 1430, 1438, 1446, 1453, 1457, 1462, 1467, 1472, 1477, 1482, - 1486, 1490, 1494, 1498, 1504, 1515, 1522, 1525, 1534, 1539, - 1549, 1554, 1562, 1566, 1576, 1579, 1585, 1591, 1598, 1608, - 1612, 1616, 1620, 1625, 1629, 1634, 1639, 1644, 1649, 1654, - 1659, 1664, 1669, 1674, 1680, 1686, 1692, 1697, 1702, 1707, - 1712, 1717, 1722, 1727, 1732, 1737, 1742, 1747, 1753, 1758, - 1763, 1768, 1773, 1778, 1783, 1788, 1793, 1798, 1803, 1808, - 1813, 1819, 1825, 1831, 1837, 1843, 1849, 1855, 1861, 1867, - 1873, 1879, 1885, 1891, 1897, 1903, 1909, 1915, 1921, 1927, - 1933, 1939, 1945, 1951, 1957, 1963, 1969, 1975, 1981, 1987, - 1993, 1999, 2005, 2011, 2017, 2023, 2029, 2035, 2041, 2047, - 2053, 2059, 2065, 2071, 2077, 2083, 2089, 2095, 2101, 2107, - 2113, 2119, 2125, 2131, 2137, 2143, 2149, 2155, 2161, 2167, - 2173, 2179, 2185, 2191, 2197, 2203, 2209, 2215, 2221, 2227, - 2233, 2239, 2245, 2251, 2257, 2263, 2269, 2275, 2281, 2287, - 2293, 2299, 2305, 2311, 2317, 2321, 2326, 2332, 2337, 2342, - 2347, 2352, 2357, 2362, 2368, 2373, 2378, 2383, 2388, 2393, - 2399, 2405, 2411, 2417, 2423, 2429, 2435, 2441, 2447, 2453, - 2459, 2465, 2471, 2477, 2482, 2487, 2492, 2497, 2502, 2507, - 2513, 2518, 2523, 2528, 2533, 2538, 2543, 2548, 2554, 2559, - 2564, 2569, 2574, 2579, 2584, 2589, 2594, 2599, 2604, 2609, - 2614, 2619, 2624, 2630, 2635, 2640, 2646, 2652, 2657, 2662, - 2667, 2673, 2678, 2683, 2688, 2694, 2699, 2704, 2709, 2715, - 2720, 2725, 2730, 2736, 2742, 2748, 2754, 2759, 2765, 2771, - 2777, 2782, 2787, 2792, 2797, 2802, 2808, 2813, 2818, 2823, - 2829, 2834, 2839, 2844, 2850, 2855, 2860, 2865, 2871, 2876, - 2881, 2886, 2892, 2897, 2902, 2907, 2913, 2918, 2923, 2928, - 2934, 2939, 2944, 2949, 2955, 2960, 2965, 2970, 2976, 2981, - 2986, 2991, 2997, 3002, 3007, 3012, 3018, 3023, 3028, 3033, - 3039, 3044, 3049, 3054, 3060, 3065, 3070, 3075, 3081, 3086, - 3091, 3096, 3102, 3107, 3112, 3118, 3124, 3130, 3136, 3143, - 3150, 3156, 3162, 3168, 3174, 3180, 3186, 3193, 3198, 3214, - 3219, 3224, 3232, 3232, 3243, 3243, 3253, 3256, 3269, 3291, - 3318, 3322, 3328, 3333, 3344, 3348, 3354, 3365, 3368, 3375, - 3379, 3380, 3386, 3387, 3388, 3389, 3390, 3391, 3392, 3394, - 3400, 3409, 3410, 3414, 3410, 3426, 3427, 3431, 3431, 3438, - 3438, 3452, 3455, 3463, 3471, 3482, 3483, 3487, 3491, 3498, - 3505, 3509, 3517, 3521, 3534, 3538, 3545, 3545, 3565, 3568, - 3574, 3586, 3598, 3602, 3609, 3609, 3624, 3624, 3640, 3640, - 3661, 3664, 3670, 3673, 3679, 3683, 3690, 3695, 3700, 3707, - 3710, 3719, 3723, 3732, 3735, 3739, 3748, 3748, 3771, 3777, - 3780, 3785, 3788 + 0, 357, 357, 363, 366, 371, 374, 377, 381, 385, + 388, 392, 396, 400, 404, 408, 412, 418, 426, 429, + 432, 435, 438, 443, 451, 458, 465, 471, 475, 482, + 485, 491, 498, 508, 516, 521, 549, 558, 564, 568, + 572, 592, 593, 594, 595, 601, 602, 607, 612, 621, + 622, 627, 635, 636, 642, 651, 652, 657, 662, 667, + 675, 676, 685, 697, 698, 707, 708, 717, 718, 727, + 728, 736, 737, 745, 746, 754, 755, 755, 773, 774, + 790, 794, 798, 802, 807, 811, 815, 819, 823, 827, + 831, 838, 841, 852, 859, 864, 869, 876, 880, 884, + 888, 893, 898, 907, 907, 918, 922, 929, 936, 939, + 946, 954, 974, 997, 1012, 1037, 1048, 1058, 1068, 1078, + 1087, 1090, 1094, 1098, 1103, 1111, 1118, 1123, 1128, 1133, + 1142, 1152, 1179, 1188, 1195, 1203, 1210, 1217, 1225, 1235, + 1242, 1253, 1259, 1262, 1269, 1273, 1277, 1286, 1296, 1299, + 1310, 1313, 1316, 1320, 1324, 1329, 1333, 1340, 1344, 1349, + 1355, 1361, 1368, 1373, 1381, 1387, 1399, 1413, 1419, 1424, + 1432, 1440, 1448, 1456, 1464, 1472, 1480, 1488, 1495, 1502, + 1506, 1511, 1516, 1521, 1526, 1531, 1536, 1540, 1544, 1548, + 1552, 1558, 1569, 1576, 1579, 1588, 1593, 1603, 1608, 1616, + 1620, 1630, 1633, 1639, 1645, 1652, 1662, 1666, 1670, 1674, + 1679, 1683, 1688, 1693, 1698, 1703, 1708, 1713, 1718, 1723, + 1728, 1734, 1740, 1746, 1751, 1756, 1761, 1766, 1771, 1776, + 1781, 1786, 1791, 1796, 1801, 1807, 1814, 1819, 1824, 1829, + 1834, 1839, 1844, 1849, 1854, 1859, 1864, 1869, 1877, 1885, + 1893, 1899, 1905, 1911, 1917, 1923, 1929, 1935, 1941, 1947, + 1953, 1959, 1965, 1971, 1977, 1983, 1989, 1995, 2001, 2007, + 2013, 2019, 2025, 2031, 2037, 2043, 2049, 2055, 2061, 2067, + 2073, 2079, 2085, 2091, 2099, 2107, 2115, 2123, 2131, 2139, + 2147, 2155, 2163, 2171, 2179, 2187, 2193, 2199, 2205, 2211, + 2217, 2223, 2229, 2235, 2241, 2247, 2253, 2259, 2265, 2271, + 2277, 2283, 2289, 2295, 2301, 2307, 2313, 2319, 2325, 2331, + 2337, 2343, 2349, 2355, 2361, 2367, 2373, 2379, 2385, 2391, + 2397, 2403, 2407, 2411, 2415, 2420, 2426, 2431, 2436, 2441, + 2446, 2451, 2456, 2462, 2467, 2472, 2477, 2482, 2487, 2493, + 2499, 2505, 2511, 2517, 2523, 2529, 2535, 2541, 2547, 2553, + 2559, 2565, 2571, 2576, 2581, 2586, 2591, 2596, 2601, 2607, + 2612, 2617, 2622, 2627, 2632, 2637, 2642, 2648, 2653, 2658, + 2663, 2668, 2673, 2678, 2683, 2688, 2693, 2698, 2703, 2708, + 2713, 2718, 2724, 2729, 2734, 2740, 2746, 2751, 2756, 2761, + 2767, 2772, 2777, 2782, 2788, 2793, 2798, 2803, 2809, 2814, + 2819, 2824, 2830, 2836, 2842, 2848, 2853, 2859, 2865, 2871, + 2876, 2881, 2886, 2891, 2896, 2902, 2907, 2912, 2917, 2923, + 2928, 2933, 2938, 2944, 2949, 2954, 2959, 2965, 2970, 2975, + 2980, 2986, 2991, 2996, 3001, 3007, 3012, 3017, 3022, 3028, + 3033, 3038, 3043, 3049, 3054, 3059, 3064, 3070, 3075, 3080, + 3085, 3091, 3096, 3101, 3106, 3112, 3117, 3122, 3127, 3133, + 3138, 3143, 3148, 3154, 3159, 3164, 3169, 3175, 3180, 3185, + 3190, 3196, 3201, 3206, 3212, 3218, 3224, 3230, 3237, 3244, + 3250, 3256, 3262, 3268, 3274, 3280, 3287, 3292, 3308, 3313, + 3318, 3326, 3326, 3337, 3337, 3347, 3350, 3363, 3385, 3412, + 3416, 3422, 3427, 3438, 3442, 3448, 3459, 3462, 3469, 3473, + 3474, 3480, 3481, 3482, 3483, 3484, 3485, 3486, 3488, 3494, + 3503, 3504, 3508, 3504, 3520, 3521, 3525, 3525, 3532, 3532, + 3546, 3549, 3557, 3565, 3576, 3577, 3581, 3585, 3592, 3599, + 3603, 3611, 3615, 3628, 3632, 3639, 3639, 3659, 3662, 3668, + 3680, 3692, 3696, 3703, 3703, 3718, 3718, 3734, 3734, 3755, + 3758, 3764, 3767, 3773, 3777, 3784, 3789, 3794, 3801, 3804, + 3813, 3817, 3826, 3829, 3833, 3842, 3842, 3884, 3890, 3893, + 3898, 3901 }; #endif @@ -1039,16 +1050,17 @@ static const char *const yytname[] = "F32MAT3X2", "F32MAT3X3", "F32MAT3X4", "F32MAT4X2", "F32MAT4X3", "F32MAT4X4", "F64MAT2X2", "F64MAT2X3", "F64MAT2X4", "F64MAT3X2", "F64MAT3X3", "F64MAT3X4", "F64MAT4X2", "F64MAT4X3", "F64MAT4X4", - "ATOMIC_UINT", "ACCSTRUCTNV", "FCOOPMATNV", "ICOOPMATNV", "UCOOPMATNV", - "SAMPLERCUBEARRAY", "SAMPLERCUBEARRAYSHADOW", "ISAMPLERCUBEARRAY", - "USAMPLERCUBEARRAY", "SAMPLER1D", "SAMPLER1DARRAY", - "SAMPLER1DARRAYSHADOW", "ISAMPLER1D", "SAMPLER1DSHADOW", "SAMPLER2DRECT", - "SAMPLER2DRECTSHADOW", "ISAMPLER2DRECT", "USAMPLER2DRECT", - "SAMPLERBUFFER", "ISAMPLERBUFFER", "USAMPLERBUFFER", "SAMPLER2DMS", - "ISAMPLER2DMS", "USAMPLER2DMS", "SAMPLER2DMSARRAY", "ISAMPLER2DMSARRAY", - "USAMPLER2DMSARRAY", "SAMPLEREXTERNALOES", "SAMPLEREXTERNAL2DY2YEXT", - "ISAMPLER1DARRAY", "USAMPLER1D", "USAMPLER1DARRAY", "F16SAMPLER1D", - "F16SAMPLER2D", "F16SAMPLER3D", "F16SAMPLER2DRECT", "F16SAMPLERCUBE", + "ATOMIC_UINT", "ACCSTRUCTNV", "ACCSTRUCTEXT", "RAYQUERYEXT", + "FCOOPMATNV", "ICOOPMATNV", "UCOOPMATNV", "SAMPLERCUBEARRAY", + "SAMPLERCUBEARRAYSHADOW", "ISAMPLERCUBEARRAY", "USAMPLERCUBEARRAY", + "SAMPLER1D", "SAMPLER1DARRAY", "SAMPLER1DARRAYSHADOW", "ISAMPLER1D", + "SAMPLER1DSHADOW", "SAMPLER2DRECT", "SAMPLER2DRECTSHADOW", + "ISAMPLER2DRECT", "USAMPLER2DRECT", "SAMPLERBUFFER", "ISAMPLERBUFFER", + "USAMPLERBUFFER", "SAMPLER2DMS", "ISAMPLER2DMS", "USAMPLER2DMS", + "SAMPLER2DMSARRAY", "ISAMPLER2DMSARRAY", "USAMPLER2DMSARRAY", + "SAMPLEREXTERNALOES", "SAMPLEREXTERNAL2DY2YEXT", "ISAMPLER1DARRAY", + "USAMPLER1D", "USAMPLER1DARRAY", "F16SAMPLER1D", "F16SAMPLER2D", + "F16SAMPLER3D", "F16SAMPLER2DRECT", "F16SAMPLERCUBE", "F16SAMPLER1DARRAY", "F16SAMPLER2DARRAY", "F16SAMPLERCUBEARRAY", "F16SAMPLERBUFFER", "F16SAMPLER2DMS", "F16SAMPLER2DMSARRAY", "F16SAMPLER1DSHADOW", "F16SAMPLER2DSHADOW", "F16SAMPLER1DARRAYSHADOW", @@ -1078,28 +1090,30 @@ static const char *const yytname[] = "F16SUBPASSINPUTMS", "LEFT_OP", "RIGHT_OP", "INC_OP", "DEC_OP", "LE_OP", "GE_OP", "EQ_OP", "NE_OP", "AND_OP", "OR_OP", "XOR_OP", "MUL_ASSIGN", "DIV_ASSIGN", "ADD_ASSIGN", "MOD_ASSIGN", "LEFT_ASSIGN", "RIGHT_ASSIGN", - "AND_ASSIGN", "XOR_ASSIGN", "OR_ASSIGN", "SUB_ASSIGN", "LEFT_PAREN", - "RIGHT_PAREN", "LEFT_BRACKET", "RIGHT_BRACKET", "LEFT_BRACE", - "RIGHT_BRACE", "DOT", "COMMA", "COLON", "EQUAL", "SEMICOLON", "BANG", - "DASH", "TILDE", "PLUS", "STAR", "SLASH", "PERCENT", "LEFT_ANGLE", - "RIGHT_ANGLE", "VERTICAL_BAR", "CARET", "AMPERSAND", "QUESTION", - "INVARIANT", "HIGH_PRECISION", "MEDIUM_PRECISION", "LOW_PRECISION", - "PRECISION", "PACKED", "RESOURCE", "SUPERP", "FLOATCONSTANT", - "INTCONSTANT", "UINTCONSTANT", "BOOLCONSTANT", "IDENTIFIER", "TYPE_NAME", - "CENTROID", "IN", "OUT", "INOUT", "STRUCT", "VOID", "WHILE", "BREAK", - "CONTINUE", "DO", "ELSE", "FOR", "IF", "DISCARD", "RETURN", "SWITCH", - "CASE", "DEFAULT", "UNIFORM", "SHARED", "BUFFER", "FLAT", "SMOOTH", - "LAYOUT", "DOUBLECONSTANT", "INT16CONSTANT", "UINT16CONSTANT", - "FLOAT16CONSTANT", "INT32CONSTANT", "UINT32CONSTANT", "INT64CONSTANT", - "UINT64CONSTANT", "SUBROUTINE", "DEMOTE", "PAYLOADNV", "PAYLOADINNV", - "HITATTRNV", "CALLDATANV", "CALLDATAINNV", "PATCH", "SAMPLE", - "NONUNIFORM", "COHERENT", "VOLATILE", "RESTRICT", "READONLY", + "AND_ASSIGN", "XOR_ASSIGN", "OR_ASSIGN", "SUB_ASSIGN", "STRING_LITERAL", + "LEFT_PAREN", "RIGHT_PAREN", "LEFT_BRACKET", "RIGHT_BRACKET", + "LEFT_BRACE", "RIGHT_BRACE", "DOT", "COMMA", "COLON", "EQUAL", + "SEMICOLON", "BANG", "DASH", "TILDE", "PLUS", "STAR", "SLASH", "PERCENT", + "LEFT_ANGLE", "RIGHT_ANGLE", "VERTICAL_BAR", "CARET", "AMPERSAND", + "QUESTION", "INVARIANT", "HIGH_PRECISION", "MEDIUM_PRECISION", + "LOW_PRECISION", "PRECISION", "PACKED", "RESOURCE", "SUPERP", + "FLOATCONSTANT", "INTCONSTANT", "UINTCONSTANT", "BOOLCONSTANT", + "IDENTIFIER", "TYPE_NAME", "CENTROID", "IN", "OUT", "INOUT", "STRUCT", + "VOID", "WHILE", "BREAK", "CONTINUE", "DO", "ELSE", "FOR", "IF", + "DISCARD", "RETURN", "SWITCH", "CASE", "DEFAULT", "UNIFORM", "SHARED", + "BUFFER", "FLAT", "SMOOTH", "LAYOUT", "DOUBLECONSTANT", "INT16CONSTANT", + "UINT16CONSTANT", "FLOAT16CONSTANT", "INT32CONSTANT", "UINT32CONSTANT", + "INT64CONSTANT", "UINT64CONSTANT", "SUBROUTINE", "DEMOTE", "PAYLOADNV", + "PAYLOADINNV", "HITATTRNV", "CALLDATANV", "CALLDATAINNV", "PAYLOADEXT", + "PAYLOADINEXT", "HITATTREXT", "CALLDATAEXT", "CALLDATAINEXT", "PATCH", + "SAMPLE", "NONUNIFORM", "COHERENT", "VOLATILE", "RESTRICT", "READONLY", "WRITEONLY", "DEVICECOHERENT", "QUEUEFAMILYCOHERENT", - "WORKGROUPCOHERENT", "SUBGROUPCOHERENT", "NONPRIVATE", "NOPERSPECTIVE", - "EXPLICITINTERPAMD", "PERVERTEXNV", "PERPRIMITIVENV", "PERVIEWNV", - "PERTASKNV", "PRECISE", "$accept", "variable_identifier", - "primary_expression", "postfix_expression", "integer_expression", - "function_call", "function_call_or_method", "function_call_generic", + "WORKGROUPCOHERENT", "SUBGROUPCOHERENT", "NONPRIVATE", + "SHADERCALLCOHERENT", "NOPERSPECTIVE", "EXPLICITINTERPAMD", + "PERVERTEXNV", "PERPRIMITIVENV", "PERVIEWNV", "PERTASKNV", "PRECISE", + "$accept", "variable_identifier", "primary_expression", + "postfix_expression", "integer_expression", "function_call", + "function_call_or_method", "function_call_generic", "function_call_header_no_parameters", "function_call_header_with_parameters", "function_call_header", "function_identifier", "unary_expression", "unary_operator", @@ -1185,16 +1199,16 @@ static const yytype_uint16 yytoknum[] = 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, - 665 + 665, 666, 667, 668, 669, 670, 671, 672, 673, 674 }; # endif -#define YYPACT_NINF -453 +#define YYPACT_NINF -457 #define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-453))) + (!!((Yystate) == (-457))) -#define YYTABLE_NINF -528 +#define YYTABLE_NINF -537 #define yytable_value_is_error(Yytable_value) \ 0 @@ -1203,79 +1217,80 @@ static const yytype_uint16 yytoknum[] = STATE-NUM. */ static const yytype_int16 yypact[] = { - 3994, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, 97, -453, -453, -453, - -453, -453, 6, -453, -453, -453, -453, -453, -453, -307, - -241, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -3, 95, 36, - 125, 6034, 82, -453, -22, -453, -453, -453, -453, 4402, - -453, -453, -453, -453, 131, -453, -453, 730, -453, -453, - 11, -453, 153, -28, 127, -453, 7, -453, 157, -453, - 6034, -453, -453, -453, 6034, 129, 134, -453, 13, -453, - 73, -453, -453, 8391, 162, -453, -453, -453, 161, 6034, - -453, 163, -453, -309, -453, -453, 27, 6831, -453, 16, - 1138, -453, -453, -453, -453, 162, 23, -453, 7221, 49, - -453, 138, -453, 87, 8391, 8391, 8391, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, -453, 68, -453, -453, -453, - 174, 60, 8781, 176, -453, 8391, -453, -453, -320, 175, - -453, 6034, 142, 4810, -453, 6034, 8391, -453, -28, -453, - 143, -453, -453, 119, 128, 32, 21, 38, 158, 160, - 165, 195, 194, 18, 183, 7611, -453, 185, 184, -453, - -453, 188, 180, 181, -453, 196, 197, 190, 8001, 198, - 8391, 187, 193, 122, -453, -453, 91, -453, 95, 204, - 205, -453, -453, -453, -453, -453, 1546, -453, -453, -453, - -453, -453, -453, -453, -453, -453, -353, 175, 7221, 69, - 7221, -453, -453, 7221, 6034, -453, 170, -453, -453, -453, - 78, -453, -453, 8391, 171, -453, -453, 8391, 207, -453, - -453, -453, 8391, -453, 142, 162, 93, -453, -453, -453, - 5218, -453, -453, -453, -453, 8391, 8391, 8391, 8391, 8391, - 8391, 8391, 8391, 8391, 8391, 8391, 8391, 8391, 8391, 8391, - 8391, 8391, 8391, 8391, -453, -453, -453, 206, 177, -453, - 1954, -453, -453, -453, 1954, -453, 8391, -453, -453, 100, - 8391, 144, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, -453, -453, -453, 8391, 8391, -453, -453, -453, - -453, -453, -453, -453, 7221, -453, 140, -453, 5626, -453, - -453, 209, 208, -453, -453, -453, 123, 175, 142, -453, - -453, -453, -453, -453, 119, 119, 128, 128, 32, 32, - 32, 32, 21, 21, 38, 158, 160, 165, 195, 194, - 8391, -453, 214, 56, -453, 1954, 3586, 172, 3178, 80, - -453, 81, -453, -453, -453, -453, -453, 6441, -453, -453, - -453, -453, 146, 8391, 215, 177, 212, 208, 186, 6034, - 219, 221, -453, -453, 3586, 220, -453, -453, -453, 8391, - 222, -453, -453, -453, 216, 2362, 8391, -453, 217, 227, - 182, 225, 2770, -453, 229, -453, -453, 7221, -453, -453, - -453, 89, 8391, 2362, 220, -453, -453, 1954, -453, 224, - 208, -453, -453, 1954, 226, -453, -453 + 4075, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, 132, -457, + -457, -457, -457, -457, -1, -457, -457, -457, -457, -457, + -457, -301, -298, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, 11, -249, 17, 30, 6160, + 20, -457, 28, -457, -457, -457, -457, 4492, -457, -457, + -457, -457, 50, -457, -457, 739, -457, -457, 16, -457, + 81, -29, 69, -457, -313, -457, 111, -457, 6160, -457, + -457, -457, 6160, 103, 106, -457, -314, -457, 72, -457, + -457, 8566, 142, -457, -457, -457, 136, 6160, -457, 144, + -457, 53, -457, -457, 76, 6974, -457, -312, 1156, -457, + -457, -457, -457, 142, -309, -457, 7372, -308, -457, 119, + -457, 65, 8566, 8566, -457, 8566, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, -457, 36, -457, -457, -457, 171, + 85, 8964, 173, -457, 8566, -457, -457, -323, 174, -457, + 6160, 139, 4909, -457, 6160, 8566, -457, -29, -457, 141, + -457, -457, 145, 99, 35, 26, 71, 156, 159, 161, + 196, 195, 23, 181, 7770, -457, 183, 182, -457, -457, + 186, 179, 180, -457, 191, 192, 187, 8168, 193, 8566, + 188, 189, 127, -457, -457, 96, -457, -249, 200, 201, + -457, -457, -457, -457, -457, 1573, -457, -457, -457, -457, + -457, -457, -457, -457, -457, -24, 174, 7372, 13, 7372, + -457, -457, 7372, 6160, -457, 166, -457, -457, -457, 86, + -457, -457, 8566, 168, -457, -457, 8566, 205, -457, -457, + -457, 8566, -457, 139, 142, 124, -457, -457, -457, 5326, + -457, -457, -457, -457, 8566, 8566, 8566, 8566, 8566, 8566, + 8566, 8566, 8566, 8566, 8566, 8566, 8566, 8566, 8566, 8566, + 8566, 8566, 8566, -457, -457, -457, 206, 172, -457, 1990, + -457, -457, -457, 1990, -457, 8566, -457, -457, 130, 8566, + 125, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, -457, -457, 8566, 8566, -457, -457, -457, -457, + -457, -457, -457, 7372, -457, 94, -457, 5743, -457, -457, + 207, 204, -457, -457, -457, 131, 174, 139, -457, -457, + -457, -457, -457, 145, 145, 99, 99, 35, 35, 35, + 35, 26, 26, 71, 156, 159, 161, 196, 195, 8566, + -457, 212, 60, -457, 1990, 3658, 169, 3241, 87, -457, + 89, -457, -457, -457, -457, -457, 6576, -457, -457, -457, + -457, 143, 8566, 211, 172, 210, 204, 184, 6160, 217, + 219, -457, -457, 3658, 218, -457, -457, -457, 8566, 220, + -457, -457, -457, 214, 2407, 8566, -457, 216, 223, 185, + 224, 2824, -457, 225, -457, -457, 7372, -457, -457, -457, + 97, 8566, 2407, 218, -457, -457, 1990, -457, 222, 204, + -457, -457, 1990, 229, -457, -457 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -1283,113 +1298,114 @@ static const yytype_int16 yypact[] = means the default is an error. */ static const yytype_uint16 yydefact[] = { - 0, 156, 203, 201, 202, 200, 207, 208, 209, 210, - 211, 212, 213, 214, 215, 204, 205, 206, 216, 217, - 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, - 327, 328, 329, 330, 331, 332, 333, 353, 354, 355, - 356, 357, 358, 359, 368, 381, 382, 369, 370, 372, - 371, 373, 374, 375, 376, 377, 378, 379, 380, 164, - 165, 229, 230, 228, 231, 238, 239, 236, 237, 234, - 235, 232, 233, 261, 262, 263, 273, 274, 275, 258, - 259, 260, 270, 271, 272, 255, 256, 257, 267, 268, - 269, 252, 253, 254, 264, 265, 266, 240, 241, 242, - 276, 277, 278, 243, 244, 245, 288, 289, 290, 246, - 247, 248, 300, 301, 302, 249, 250, 251, 312, 313, - 314, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 303, - 304, 305, 306, 307, 308, 309, 310, 311, 315, 316, - 317, 318, 319, 320, 321, 322, 323, 325, 324, 484, - 485, 486, 337, 338, 361, 364, 326, 335, 336, 352, - 334, 383, 384, 387, 388, 389, 391, 392, 393, 395, - 396, 397, 399, 400, 474, 475, 360, 362, 363, 339, - 340, 341, 385, 342, 346, 347, 350, 390, 394, 398, - 343, 344, 348, 349, 386, 345, 351, 430, 432, 433, - 434, 436, 437, 438, 440, 441, 442, 444, 445, 446, - 448, 449, 450, 452, 453, 454, 456, 457, 458, 460, - 461, 462, 464, 465, 466, 468, 469, 470, 472, 473, - 431, 435, 439, 443, 447, 455, 459, 463, 451, 467, - 471, 365, 366, 367, 401, 410, 412, 406, 411, 413, - 414, 416, 417, 418, 420, 421, 422, 424, 425, 426, - 428, 429, 402, 403, 404, 415, 405, 407, 408, 409, - 419, 423, 427, 476, 477, 480, 481, 482, 483, 478, - 479, 575, 131, 489, 490, 491, 0, 488, 160, 158, - 159, 157, 0, 199, 161, 162, 163, 133, 132, 0, - 183, 169, 170, 168, 171, 172, 166, 167, 185, 173, - 179, 180, 181, 182, 174, 175, 176, 177, 178, 134, - 135, 136, 137, 138, 139, 146, 574, 0, 576, 0, - 108, 107, 0, 119, 124, 153, 152, 150, 154, 0, - 147, 149, 155, 129, 195, 151, 487, 0, 571, 573, - 0, 494, 0, 0, 0, 96, 0, 93, 0, 106, - 0, 115, 109, 117, 0, 118, 0, 94, 125, 99, - 0, 148, 130, 0, 188, 194, 1, 572, 0, 0, - 492, 143, 145, 0, 141, 186, 0, 0, 97, 0, - 0, 577, 110, 114, 116, 112, 120, 111, 0, 126, - 102, 0, 100, 0, 0, 0, 0, 42, 41, 43, - 40, 5, 6, 7, 8, 2, 15, 13, 14, 16, - 9, 10, 11, 12, 3, 17, 36, 19, 24, 25, - 0, 0, 29, 0, 197, 0, 35, 33, 0, 189, - 95, 0, 0, 0, 496, 0, 0, 140, 0, 184, - 0, 190, 44, 48, 51, 54, 59, 62, 64, 66, - 68, 70, 72, 74, 0, 0, 98, 0, 522, 531, - 535, 0, 0, 0, 556, 0, 0, 0, 0, 0, - 0, 0, 0, 44, 77, 90, 0, 509, 0, 155, - 129, 512, 533, 511, 519, 510, 0, 513, 514, 537, - 515, 544, 516, 517, 552, 518, 0, 113, 0, 121, - 0, 504, 128, 0, 0, 104, 0, 101, 37, 38, - 0, 21, 22, 0, 0, 27, 26, 0, 199, 30, - 32, 39, 0, 196, 0, 502, 0, 500, 495, 497, - 0, 92, 144, 142, 187, 0, 0, 0, 0, 0, + 0, 157, 210, 208, 209, 207, 214, 215, 216, 217, + 218, 219, 220, 221, 222, 211, 212, 213, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 336, 337, 338, 339, 340, 341, 342, 362, 363, 364, + 365, 366, 367, 368, 377, 390, 391, 378, 379, 381, + 380, 382, 383, 384, 385, 386, 387, 388, 389, 165, + 166, 236, 237, 235, 238, 245, 246, 243, 244, 241, + 242, 239, 240, 268, 269, 270, 280, 281, 282, 265, + 266, 267, 277, 278, 279, 262, 263, 264, 274, 275, + 276, 259, 260, 261, 271, 272, 273, 247, 248, 249, + 283, 284, 285, 250, 251, 252, 295, 296, 297, 253, + 254, 255, 307, 308, 309, 256, 257, 258, 319, 320, + 321, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 298, 299, 300, 301, 302, 303, 304, 305, 306, 310, + 311, 312, 313, 314, 315, 316, 317, 318, 322, 323, + 324, 325, 326, 327, 328, 329, 330, 334, 331, 332, + 333, 493, 494, 495, 346, 347, 370, 373, 335, 344, + 345, 361, 343, 392, 393, 396, 397, 398, 400, 401, + 402, 404, 405, 406, 408, 409, 483, 484, 369, 371, + 372, 348, 349, 350, 394, 351, 355, 356, 359, 399, + 403, 407, 352, 353, 357, 358, 395, 354, 360, 439, + 441, 442, 443, 445, 446, 447, 449, 450, 451, 453, + 454, 455, 457, 458, 459, 461, 462, 463, 465, 466, + 467, 469, 470, 471, 473, 474, 475, 477, 478, 479, + 481, 482, 440, 444, 448, 452, 456, 464, 468, 472, + 460, 476, 480, 374, 375, 376, 410, 419, 421, 415, + 420, 422, 423, 425, 426, 427, 429, 430, 431, 433, + 434, 435, 437, 438, 411, 412, 413, 424, 414, 416, + 417, 418, 428, 432, 436, 485, 486, 489, 490, 491, + 492, 487, 488, 584, 132, 498, 499, 500, 0, 497, + 161, 159, 160, 158, 0, 206, 162, 163, 164, 134, + 133, 0, 190, 171, 173, 169, 175, 177, 172, 174, + 170, 176, 178, 167, 168, 192, 179, 186, 187, 188, + 189, 180, 181, 182, 183, 184, 185, 135, 136, 137, + 138, 139, 140, 147, 583, 0, 585, 0, 109, 108, + 0, 120, 125, 154, 153, 151, 155, 0, 148, 150, + 156, 130, 202, 152, 496, 0, 580, 582, 0, 503, + 0, 0, 0, 97, 0, 94, 0, 107, 0, 116, + 110, 118, 0, 119, 0, 95, 126, 100, 0, 149, + 131, 0, 195, 201, 1, 581, 0, 0, 501, 144, + 146, 0, 142, 193, 0, 0, 98, 0, 0, 586, + 111, 115, 117, 113, 121, 112, 0, 127, 103, 0, + 101, 0, 0, 0, 9, 0, 43, 42, 44, 41, + 5, 6, 7, 8, 2, 16, 14, 15, 17, 10, + 11, 12, 13, 3, 18, 37, 20, 25, 26, 0, + 0, 30, 0, 204, 0, 36, 34, 0, 196, 96, + 0, 0, 0, 505, 0, 0, 141, 0, 191, 0, + 197, 45, 49, 52, 55, 60, 63, 65, 67, 69, + 71, 73, 75, 0, 0, 99, 0, 531, 540, 544, + 0, 0, 0, 565, 0, 0, 0, 0, 0, 0, + 0, 0, 45, 78, 91, 0, 518, 0, 156, 130, + 521, 542, 520, 528, 519, 0, 522, 523, 546, 524, + 553, 525, 526, 561, 527, 0, 114, 0, 122, 0, + 513, 129, 0, 0, 105, 0, 102, 38, 39, 0, + 22, 23, 0, 0, 28, 27, 0, 206, 31, 33, + 40, 0, 203, 0, 511, 0, 509, 504, 506, 0, + 93, 145, 143, 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 75, 191, 192, 0, 0, 521, - 0, 554, 567, 566, 0, 558, 0, 570, 568, 0, - 0, 0, 551, 520, 80, 81, 83, 82, 85, 86, - 87, 88, 89, 84, 79, 0, 0, 536, 532, 534, - 538, 545, 553, 123, 0, 507, 0, 127, 0, 105, - 4, 0, 23, 20, 31, 198, 0, 503, 0, 498, - 493, 45, 46, 47, 50, 49, 52, 53, 57, 58, - 55, 56, 60, 61, 63, 65, 67, 69, 71, 73, - 0, 193, 581, 0, 579, 523, 0, 0, 0, 0, - 569, 0, 550, 78, 91, 122, 505, 0, 103, 18, - 499, 501, 0, 0, 0, 0, 0, 542, 0, 0, - 0, 0, 561, 560, 563, 529, 546, 506, 508, 0, - 0, 578, 580, 524, 0, 0, 0, 562, 0, 0, - 541, 0, 0, 539, 0, 76, 582, 0, 526, 555, - 525, 0, 564, 0, 529, 528, 530, 548, 543, 0, - 565, 559, 540, 549, 0, 557, 547 + 0, 0, 0, 76, 198, 199, 0, 0, 530, 0, + 563, 576, 575, 0, 567, 0, 579, 577, 0, 0, + 0, 560, 529, 81, 82, 84, 83, 86, 87, 88, + 89, 90, 85, 80, 0, 0, 545, 541, 543, 547, + 554, 562, 124, 0, 516, 0, 128, 0, 106, 4, + 0, 24, 21, 32, 205, 0, 512, 0, 507, 502, + 46, 47, 48, 51, 50, 53, 54, 58, 59, 56, + 57, 61, 62, 64, 66, 68, 70, 72, 74, 0, + 200, 590, 0, 588, 532, 0, 0, 0, 0, 578, + 0, 559, 79, 92, 123, 514, 0, 104, 19, 508, + 510, 0, 0, 0, 0, 0, 551, 0, 0, 0, + 0, 570, 569, 572, 538, 555, 515, 517, 0, 0, + 587, 589, 533, 0, 0, 0, 571, 0, 0, 550, + 0, 0, 548, 0, 77, 591, 0, 535, 564, 534, + 0, 573, 0, 538, 537, 539, 557, 552, 0, 574, + 568, 549, 558, 0, 566, 556 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, - -453, -453, 8696, -453, -89, -88, -122, -84, -19, -18, - -17, -16, -20, -15, -453, -85, -453, -98, -453, -110, - -119, 2, -453, -453, -453, 4, -453, -453, -453, 189, - 191, 192, -453, -453, -339, -453, -453, -453, -453, 98, - -453, -37, -44, -453, 9, -453, 0, -71, -453, -453, - -453, -453, 261, -453, -453, -453, -452, -137, 20, -68, - -209, -453, -96, -198, -326, -453, -136, -453, -453, -146, - -144, -453, -453, 200, -265, -87, -453, 57, -453, -112, - -453, 59, -453, -453, -453, -453, 61, -453, -453, -453, - -453, -453, -453, -453, -453, 228, -453, -453, -453, -453, - -99 + -457, -457, -457, -457, -457, -457, -457, -457, -457, -457, + -457, -457, 8868, -457, -87, -84, -127, -93, -33, -31, + -27, -25, -28, -26, -457, -86, -457, -103, -457, -111, + -125, 2, -457, -457, -457, 4, -457, -457, -457, 176, + 194, 178, -457, -457, -337, -457, -457, -457, -457, 95, + -457, -37, -46, -457, 9, -457, 0, -63, -457, -457, + -457, -457, 263, -457, -457, -457, -456, -140, 10, -73, + -211, -457, -102, -198, -321, -457, -144, -457, -457, -155, + -154, -457, -457, 198, -274, -97, -457, 46, -457, -118, + -457, 51, -457, -457, -457, -457, 52, -457, -457, -457, + -457, -457, -457, -457, -457, 213, -457, -457, -457, -457, + -105 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 434, 435, 436, 621, 437, 438, 439, 440, 441, - 442, 443, 493, 445, 463, 464, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 494, 650, 495, 605, 496, - 552, 497, 337, 524, 413, 498, 339, 340, 341, 371, - 372, 373, 342, 343, 344, 345, 346, 347, 393, 394, - 348, 349, 350, 351, 446, 396, 447, 399, 384, 385, - 448, 354, 355, 356, 455, 389, 453, 454, 546, 547, - 522, 616, 501, 502, 503, 504, 505, 580, 676, 709, - 700, 701, 702, 710, 506, 507, 508, 509, 703, 680, - 510, 511, 704, 724, 512, 513, 514, 656, 584, 658, - 684, 698, 699, 515, 357, 358, 359, 368, 516, 653, - 654 + -1, 443, 444, 445, 630, 446, 447, 448, 449, 450, + 451, 452, 502, 454, 472, 473, 474, 475, 476, 477, + 478, 479, 480, 481, 482, 503, 659, 504, 614, 505, + 561, 506, 345, 533, 421, 507, 347, 348, 349, 379, + 380, 381, 350, 351, 352, 353, 354, 355, 401, 402, + 356, 357, 358, 359, 455, 404, 456, 407, 392, 393, + 457, 362, 363, 364, 464, 397, 462, 463, 555, 556, + 531, 625, 510, 511, 512, 513, 514, 589, 685, 718, + 709, 710, 711, 719, 515, 516, 517, 518, 712, 689, + 519, 520, 713, 733, 521, 522, 523, 665, 593, 667, + 693, 707, 708, 524, 365, 366, 367, 376, 525, 662, + 663 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -1397,161 +1413,122 @@ static const yytype_int16 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 353, 542, 336, 550, 338, 481, 457, 363, 484, 352, - 485, 486, 458, 543, 489, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 618, 364, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 374, 381, 530, 409, 609, 613, - 521, 615, 474, 449, 617, 655, 549, 678, 562, 563, - 573, 365, 391, 397, 361, 560, 561, 407, 378, 397, - 381, 398, 475, 374, 517, 519, 408, 566, 567, 397, - 476, 375, 459, 392, 539, 678, 518, 366, 460, 382, - 352, 369, 451, 564, 565, 574, 362, 353, 352, 336, - 388, 338, 297, 531, 532, 475, 352, 302, 303, 708, - 375, 551, 523, 674, 375, 536, 716, 675, 589, 352, - 591, 537, -34, 352, 533, 475, 657, 708, 534, 452, - 577, 410, 614, 620, 411, 685, 686, 412, 352, 606, - 500, 606, 606, 376, 719, 665, 377, 381, 526, 499, - 606, 527, 606, 549, 628, 607, 451, 629, 451, 367, - 521, 606, 521, 622, 660, 521, 594, 595, 596, 597, - 598, 599, 600, 601, 602, 603, 293, 294, 295, 624, - 638, 639, 640, 641, 628, 604, 370, 670, 555, 556, - 557, 544, 723, 452, 558, 452, 559, 609, 688, 666, - 352, 667, 352, 383, 352, 606, 662, 606, 689, 634, - 635, 390, 636, 637, 627, 400, 659, 395, 397, 405, - 661, 549, 642, 643, 406, 450, 456, 451, 525, 535, - 540, 475, 545, 554, 568, 569, 571, 572, 718, 570, - 575, 578, 581, 579, 582, 583, 500, 663, 664, 592, - 585, 586, 590, 451, 587, 499, 521, 593, -35, -33, - 619, 623, -28, 651, 452, 609, 669, 652, 673, 606, - 681, 693, 691, 352, 695, 696, 694, 706, -527, 707, - 672, 712, 713, 478, 714, 726, 677, 717, 725, 644, - 452, 645, 648, 646, 690, 647, 553, 360, 649, 352, - 671, 402, 682, 403, 626, 715, 404, 721, 401, 521, - 722, 683, 697, 610, 677, 611, 692, 612, 0, 0, - 500, 451, 0, 0, 500, 387, 711, 0, 551, 499, - 0, 705, 0, 499, 0, 0, 0, 0, 0, 0, - 0, 0, 720, 0, 0, 0, 0, 0, 0, 521, - 0, 0, 0, 0, 0, 0, 0, 0, 452, 679, - 0, 0, 0, 0, 0, 0, 0, 352, 0, 0, - 0, 0, 0, 0, 0, 381, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 679, 0, 0, - 0, 0, 0, 0, 0, 500, 500, 0, 500, 0, - 0, 0, 0, 0, 499, 499, 0, 499, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 382, - 0, 0, 0, 0, 500, 0, 0, 0, 352, 0, - 0, 0, 0, 499, 0, 500, 0, 0, 0, 0, - 0, 0, 500, 0, 499, 0, 0, 0, 0, 0, - 0, 499, 0, 500, 0, 0, 0, 500, 0, 0, - 0, 0, 499, 500, 0, 0, 499, 0, 0, 0, - 386, 0, 499, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, - 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, - 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, - 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, - 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 289, 290, 0, 0, 0, 0, 0, 0, 0, + 361, 551, 344, 415, 346, 405, 405, 484, 559, 360, + 405, 484, 416, 552, 406, 485, 371, 527, 532, 372, + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 627, 375, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, + 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, + 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + 292, 389, 382, 530, 539, 664, 622, 618, 624, 483, + 369, 626, 558, 417, 399, 571, 572, 582, 687, 458, + 569, 570, 484, 540, 541, 377, 389, 490, 373, 623, + 493, 382, 494, 495, 384, 400, 498, 385, 548, 383, + 526, 528, 370, -35, 378, 542, 687, 390, 360, 543, + 460, 573, 574, 583, 374, 361, 360, 344, 396, 346, + 299, 466, 575, 576, 360, 304, 305, 467, 383, 560, + 683, 386, 383, 717, 684, 391, 598, 360, 600, 535, + 725, 360, 536, 418, 468, 666, 419, 461, 586, 420, + 469, 717, 398, 545, 629, 694, 360, 695, 509, 546, + 615, 615, 674, 615, 389, 728, 675, 508, 676, 558, + 615, 615, 403, 616, 530, 460, 530, 460, 567, 530, + 568, 631, 408, 603, 604, 605, 606, 607, 608, 609, + 610, 611, 612, 633, 647, 648, 649, 650, 637, 615, + 671, 638, 732, 613, 615, 637, 413, 669, 679, 414, + 553, 405, 461, 459, 461, 697, 618, 615, 698, 360, + 465, 360, 534, 360, 295, 296, 297, 564, 565, 566, + 643, 644, 651, 652, 668, 645, 646, 558, 670, 544, + 549, 636, 554, 484, 563, 577, 460, 578, 579, 580, + 581, 584, 587, 590, 588, 727, 591, 592, 594, 595, + 599, 672, 673, 601, 596, 509, 602, -36, -34, 628, + 530, 632, 460, -29, 508, 661, 660, 678, 615, 682, + 690, 700, 702, 461, 618, 704, 705, 703, 715, -536, + 716, 722, 360, 721, 653, 487, 726, 654, 681, 734, + 723, 735, 655, 657, 686, 656, 658, 699, 411, 461, + 412, 368, 562, 635, 680, 691, 724, 730, 360, 731, + 692, 619, 410, 530, 409, 706, 620, 621, 395, 701, + 0, 0, 686, 0, 0, 0, 0, 0, 0, 509, + 460, 0, 0, 509, 720, 714, 560, 0, 508, 0, + 0, 0, 508, 0, 0, 0, 0, 0, 0, 0, + 729, 0, 0, 530, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 461, 688, 0, + 0, 0, 0, 0, 0, 0, 360, 0, 0, 0, + 0, 0, 389, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 688, 0, 0, 0, + 0, 0, 0, 0, 509, 509, 0, 509, 0, 0, + 0, 0, 0, 508, 508, 0, 508, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 390, 0, + 0, 0, 0, 509, 0, 0, 0, 360, 0, 0, + 0, 0, 508, 0, 509, 0, 0, 0, 0, 0, + 0, 509, 0, 508, 0, 0, 0, 0, 0, 0, + 508, 0, 509, 0, 0, 0, 509, 0, 0, 0, + 0, 508, 509, 0, 0, 508, 0, 0, 0, 394, + 0, 508, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 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, 291, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 292, 293, - 294, 295, 296, 0, 0, 0, 0, 0, 0, 0, - 0, 297, 298, 299, 300, 301, 302, 303, 0, 0, + 0, 0, 0, 0, 0, 0, 293, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 304, 305, 306, 307, 308, 309, 0, 0, 0, 0, - 0, 0, 0, 0, 310, 0, 311, 312, 313, 314, + 294, 295, 296, 297, 298, 0, 0, 0, 0, 0, + 0, 0, 0, 299, 300, 301, 302, 303, 304, 305, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 306, 307, 308, 309, 310, 311, 0, 0, + 0, 0, 0, 0, 0, 0, 312, 0, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, - 335, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, - 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, - 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 0, 0, 414, 415, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 416, 0, 477, 0, 478, 479, 0, 0, - 0, 0, 480, 417, 418, 419, 420, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 292, 293, 294, 295, - 296, 0, 0, 0, 421, 422, 423, 424, 425, 297, - 298, 299, 300, 301, 302, 303, 481, 482, 483, 484, - 0, 485, 486, 487, 488, 489, 490, 491, 304, 305, - 306, 307, 308, 309, 426, 427, 428, 429, 430, 431, - 432, 433, 310, 492, 311, 312, 313, 314, 315, 316, - 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 331, 332, 333, 334, 335, 1, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, @@ -1580,19 +1557,145 @@ static const yytype_int16 yytable[] = 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 0, - 0, 414, 415, 0, 0, 0, 0, 0, 0, 0, + 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + 292, 0, 0, 422, 423, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 416, 0, 477, 0, 478, 608, 0, 0, 0, 0, - 480, 417, 418, 419, 420, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 292, 293, 294, 295, 296, 0, - 0, 0, 421, 422, 423, 424, 425, 297, 298, 299, - 300, 301, 302, 303, 481, 482, 483, 484, 0, 485, - 486, 487, 488, 489, 490, 491, 304, 305, 306, 307, - 308, 309, 426, 427, 428, 429, 430, 431, 432, 433, - 310, 492, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 331, 332, 333, 334, 335, 1, 2, 3, + 0, 0, 424, 425, 0, 486, 0, 487, 488, 0, + 0, 0, 0, 489, 426, 427, 428, 429, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 294, 295, 296, + 297, 298, 0, 0, 0, 430, 431, 432, 433, 434, + 299, 300, 301, 302, 303, 304, 305, 490, 491, 492, + 493, 0, 494, 495, 496, 497, 498, 499, 500, 306, + 307, 308, 309, 310, 311, 435, 436, 437, 438, 439, + 440, 441, 442, 312, 501, 313, 314, 315, 316, 317, + 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 343, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 0, 0, + 422, 423, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 424, + 425, 0, 486, 0, 487, 617, 0, 0, 0, 0, + 489, 426, 427, 428, 429, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 294, 295, 296, 297, 298, 0, + 0, 0, 430, 431, 432, 433, 434, 299, 300, 301, + 302, 303, 304, 305, 490, 491, 492, 493, 0, 494, + 495, 496, 497, 498, 499, 500, 306, 307, 308, 309, + 310, 311, 435, 436, 437, 438, 439, 440, 441, 442, + 312, 501, 313, 314, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, + 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, + 341, 342, 343, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 0, 0, 422, 423, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 424, 425, 0, 486, + 0, 487, 0, 0, 0, 0, 0, 489, 426, 427, + 428, 429, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 294, 295, 296, 297, 298, 0, 0, 0, 430, + 431, 432, 433, 434, 299, 300, 301, 302, 303, 304, + 305, 490, 491, 492, 493, 0, 494, 495, 496, 497, + 498, 499, 500, 306, 307, 308, 309, 310, 311, 435, + 436, 437, 438, 439, 440, 441, 442, 312, 501, 313, + 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, + 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, + 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, + 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, + 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, + 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, + 291, 292, 0, 0, 422, 423, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 424, 425, 0, 486, 0, 408, 0, + 0, 0, 0, 0, 489, 426, 427, 428, 429, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 294, 295, + 296, 297, 298, 0, 0, 0, 430, 431, 432, 433, + 434, 299, 300, 301, 302, 303, 304, 305, 490, 491, + 492, 493, 0, 494, 495, 496, 497, 498, 499, 500, + 306, 307, 308, 309, 310, 311, 435, 436, 437, 438, + 439, 440, 441, 442, 312, 501, 313, 314, 315, 316, + 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, + 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, + 337, 338, 339, 340, 341, 342, 343, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, @@ -1621,19 +1724,145 @@ static const yytype_int16 yytable[] = 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 0, 0, 414, - 415, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 416, 0, - 477, 0, 478, 0, 0, 0, 0, 0, 480, 417, - 418, 419, 420, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 292, 293, 294, 295, 296, 0, 0, 0, - 421, 422, 423, 424, 425, 297, 298, 299, 300, 301, - 302, 303, 481, 482, 483, 484, 0, 485, 486, 487, - 488, 489, 490, 491, 304, 305, 306, 307, 308, 309, - 426, 427, 428, 429, 430, 431, 432, 433, 310, 492, - 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 331, 332, 333, 334, 335, 1, 2, 3, 4, 5, + 284, 285, 286, 287, 288, 289, 290, 291, 292, 0, + 0, 422, 423, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 424, 425, 0, 486, 0, 0, 0, 0, 0, 0, + 0, 489, 426, 427, 428, 429, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 294, 295, 296, 297, 298, + 0, 0, 0, 430, 431, 432, 433, 434, 299, 300, + 301, 302, 303, 304, 305, 490, 491, 492, 493, 0, + 494, 495, 496, 497, 498, 499, 500, 306, 307, 308, + 309, 310, 311, 435, 436, 437, 438, 439, 440, 441, + 442, 312, 501, 313, 314, 315, 316, 317, 318, 319, + 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, + 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 343, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 0, 0, 422, 423, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 424, 425, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 489, 426, + 427, 428, 429, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 294, 295, 296, 297, 298, 0, 0, 0, + 430, 431, 432, 433, 434, 299, 300, 301, 302, 303, + 304, 305, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 306, 307, 308, 309, 310, 311, + 435, 436, 437, 438, 439, 440, 441, 442, 312, 0, + 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, + 343, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, + 290, 291, 292, 0, 0, 422, 423, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 424, 425, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 426, 427, 428, 429, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 294, + 295, 296, 297, 0, 0, 0, 0, 430, 431, 432, + 433, 434, 299, 300, 301, 302, 303, 304, 305, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 306, 307, 308, 309, 310, 311, 435, 436, 437, + 438, 439, 440, 441, 442, 312, 0, 313, 314, 315, + 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, + 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 343, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, + 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, 293, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 294, 295, 296, 297, + 298, 0, 0, 0, 0, 0, 0, 0, 0, 299, + 300, 301, 302, 303, 304, 305, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 306, 307, + 308, 309, 310, 311, 0, 0, 0, 0, 0, 0, + 0, 0, 312, 0, 313, 314, 315, 316, 317, 318, + 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, + 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, + 339, 340, 341, 342, 343, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, @@ -1662,100 +1891,61 @@ static const yytype_int16 yytable[] = 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 0, 0, 414, 415, 0, + 286, 287, 288, 289, 290, 291, 292, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 416, 0, 477, 0, - 400, 0, 0, 0, 0, 0, 480, 417, 418, 419, - 420, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 292, 293, 294, 295, 296, 0, 0, 0, 421, 422, - 423, 424, 425, 297, 298, 299, 300, 301, 302, 303, - 481, 482, 483, 484, 0, 485, 486, 487, 488, 489, - 490, 491, 304, 305, 306, 307, 308, 309, 426, 427, - 428, 429, 430, 431, 432, 433, 310, 492, 311, 312, - 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, - 333, 334, 335, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, - 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, - 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, - 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, - 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 289, 290, 0, 0, 414, 415, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 416, 0, 477, 0, 0, 0, - 0, 0, 0, 0, 480, 417, 418, 419, 420, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 292, 293, - 294, 295, 296, 0, 0, 0, 421, 422, 423, 424, - 425, 297, 298, 299, 300, 301, 302, 303, 481, 482, - 483, 484, 0, 485, 486, 487, 488, 489, 490, 491, - 304, 305, 306, 307, 308, 309, 426, 427, 428, 429, - 430, 431, 432, 433, 310, 492, 311, 312, 313, 314, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 387, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 294, 295, 296, 297, 0, 0, 0, + 0, 0, 0, 0, 0, 388, 299, 300, 301, 302, + 303, 304, 305, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 306, 307, 308, 309, 310, + 311, 0, 0, 0, 0, 0, 0, 0, 0, 312, + 0, 313, 314, 315, 316, 317, 318, 319, 320, 321, + 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, + 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 343, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 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, 557, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 294, 295, 296, 297, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 299, 300, 301, 302, 303, 304, 305, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 306, 307, 308, 309, 310, 311, 0, 0, + 0, 0, 0, 0, 0, 0, 312, 0, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, - 335, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, - 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, - 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 0, 0, 414, 415, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 416, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 480, 417, 418, 419, 420, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 292, 293, 294, 295, - 296, 0, 0, 0, 421, 422, 423, 424, 425, 297, - 298, 299, 300, 301, 302, 303, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 304, 305, - 306, 307, 308, 309, 426, 427, 428, 429, 430, 431, - 432, 433, 310, 0, 311, 312, 313, 314, 315, 316, - 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 331, 332, 333, 334, 335, 1, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, @@ -1784,25 +1974,149 @@ static const yytype_int16 yytable[] = 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 0, - 0, 414, 415, 0, 0, 0, 0, 0, 0, 0, + 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + 292, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 417, 418, 419, 420, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 292, 293, 294, 295, 0, 0, - 0, 0, 421, 422, 423, 424, 425, 297, 298, 299, - 300, 301, 302, 303, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 304, 305, 306, 307, - 308, 309, 426, 427, 428, 429, 430, 431, 432, 433, - 310, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 331, 332, 333, 334, 335, 1, 2, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 639, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 294, 295, 296, + 297, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 299, 300, 301, 302, 303, 304, 305, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 306, + 307, 308, 309, 310, 311, 0, 0, 0, 0, 0, + 0, 0, 0, 312, 0, 313, 314, 315, 316, 317, + 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 343, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 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, 677, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 294, 295, 296, 297, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 299, 300, 301, + 302, 303, 304, 305, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 306, 307, 308, 309, + 310, 311, 0, 0, 0, 0, 0, 0, 0, 0, + 312, 0, 313, 314, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, + 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, + 341, 342, 343, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 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, + 0, 294, 295, 296, 297, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 299, 300, 301, 302, 303, 304, + 305, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 306, 307, 308, 309, 310, 311, 0, + 0, 0, 0, 0, 0, 0, 0, 312, 0, 313, + 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, + 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 0, 0, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, + 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, + 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + 292, 0, 0, 422, 423, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 424, 425, 0, 0, 0, 529, 696, 0, + 0, 0, 0, 0, 426, 427, 428, 429, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 430, 431, 432, 433, 434, + 299, 0, 0, 0, 0, 304, 305, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 435, 436, 437, 438, 439, + 440, 441, 442, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 325, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 54, 55, 56, 57, 58, 0, 0, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, @@ -1825,25 +2139,24 @@ static const yytype_int16 yytable[] = 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 0, 0, 0, + 284, 285, 286, 287, 288, 289, 290, 291, 292, 0, + 0, 422, 423, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 424, 425, 0, 0, 470, 0, 0, 0, 0, 0, + 0, 0, 426, 427, 428, 429, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 291, 0, + 0, 0, 0, 430, 431, 432, 433, 434, 299, 0, + 0, 0, 0, 304, 305, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 292, 293, 294, 295, 296, 0, 0, 0, - 0, 0, 0, 0, 0, 297, 298, 299, 300, 301, - 302, 303, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 304, 305, 306, 307, 308, 309, - 0, 0, 0, 0, 0, 0, 0, 0, 310, 0, - 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 331, 332, 333, 334, 335, 1, 2, 3, 4, 5, + 0, 0, 0, 435, 436, 437, 438, 439, 440, 441, + 442, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 325, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 56, 57, 58, 0, 0, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, @@ -1866,25 +2179,24 @@ static const yytype_int16 yytable[] = 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 0, 0, 0, 0, 0, + 286, 287, 288, 289, 290, 291, 292, 0, 0, 422, + 423, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 424, 425, + 0, 0, 0, 529, 0, 0, 0, 0, 0, 0, + 426, 427, 428, 429, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 430, 431, 432, 433, 434, 299, 0, 0, 0, + 0, 304, 305, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 379, 0, 0, 0, + 0, 435, 436, 437, 438, 439, 440, 441, 442, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 292, 293, 294, 295, 0, 0, 0, 0, 0, 0, - 0, 0, 380, 297, 298, 299, 300, 301, 302, 303, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 304, 305, 306, 307, 308, 309, 0, 0, - 0, 0, 0, 0, 0, 0, 310, 0, 311, 312, - 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, - 333, 334, 335, 1, 2, 3, 4, 5, 6, 7, + 0, 0, 0, 325, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 58, 0, 0, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, @@ -1907,25 +2219,24 @@ static const yytype_int16 yytable[] = 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 289, 290, 0, 0, 0, 0, 0, 0, 0, + 288, 289, 290, 291, 292, 0, 0, 422, 423, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 548, + 0, 0, 0, 0, 0, 0, 424, 425, 0, 0, + 585, 0, 0, 0, 0, 0, 0, 0, 426, 427, + 428, 429, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 430, + 431, 432, 433, 434, 299, 0, 0, 0, 0, 304, + 305, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, + 436, 437, 438, 439, 440, 441, 442, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 292, 293, - 294, 295, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 297, 298, 299, 300, 301, 302, 303, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 304, 305, 306, 307, 308, 309, 0, 0, 0, 0, - 0, 0, 0, 0, 310, 0, 311, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, - 335, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 325, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 0, + 0, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, @@ -1948,24 +2259,23 @@ static const yytype_int16 yytable[] = 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 290, 291, 292, 0, 0, 422, 423, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 630, 0, 0, + 0, 0, 0, 0, 424, 425, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 597, 426, 427, 428, 429, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 292, 293, 294, 295, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 297, - 298, 299, 300, 301, 302, 303, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 304, 305, - 306, 307, 308, 309, 0, 0, 0, 0, 0, 0, - 0, 0, 310, 0, 311, 312, 313, 314, 315, 316, - 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 331, 332, 333, 334, 335, 1, + 0, 0, 0, 0, 0, 0, 0, 430, 431, 432, + 433, 434, 299, 0, 0, 0, 0, 304, 305, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 435, 436, 437, + 438, 439, 440, 441, 442, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 325, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 52, 53, 54, 55, 56, 57, 58, 0, 0, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, @@ -1988,25 +2298,24 @@ static const yytype_int16 yytable[] = 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 0, + 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + 292, 0, 0, 422, 423, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 424, 425, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 426, 427, 428, 429, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 668, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 430, 431, 432, 433, 434, + 299, 0, 0, 0, 0, 304, 305, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 292, 293, 294, 295, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 297, 298, 299, - 300, 301, 302, 303, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 304, 305, 306, 307, - 308, 309, 0, 0, 0, 0, 0, 0, 0, 0, - 310, 0, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 331, 332, 333, 334, 335, 1, 2, 3, + 0, 0, 0, 0, 0, 435, 436, 437, 438, 439, + 440, 441, 442, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 325, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 54, 55, 56, 57, 58, 0, 0, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, @@ -2029,301 +2338,27 @@ static const yytype_int16 yytable[] = 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 0, 0, 0, + 284, 285, 286, 287, 288, 289, 290, 291, 292, 453, + 0, 422, 423, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 471, 0, 0, 0, 0, 0, 0, + 424, 425, 0, 0, 0, 0, 0, 0, 0, 0, + 537, 538, 426, 427, 428, 429, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 430, 431, 432, 433, 434, 299, 0, + 0, 0, 550, 304, 547, 0, 0, 0, 0, 0, + 0, 0, 0, 471, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 435, 436, 437, 438, 439, 440, 441, + 442, 0, 471, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 325, 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, 0, 292, 293, 294, 295, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 297, 298, 299, 300, 301, - 302, 303, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 304, 305, 306, 307, 308, 309, - 0, 0, 0, 0, 0, 0, 0, 0, 310, 0, - 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 331, 332, 333, 334, 335, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 0, 0, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 0, 0, 414, 415, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 634, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 416, 0, 0, 0, 520, - 687, 0, 0, 0, 0, 0, 417, 418, 419, 420, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 421, 422, 423, - 424, 425, 297, 0, 0, 0, 0, 302, 303, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 426, 427, 428, - 429, 430, 431, 432, 433, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 318, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 0, 0, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 0, 0, 414, 415, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 416, 0, 0, 461, 0, - 0, 0, 0, 0, 0, 0, 417, 418, 419, 420, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 421, 422, 423, - 424, 425, 297, 0, 0, 0, 0, 302, 303, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 426, 427, 428, - 429, 430, 431, 432, 433, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 318, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 0, 0, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 0, 0, 414, 415, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 416, 0, 0, 0, 520, - 0, 0, 0, 0, 0, 0, 417, 418, 419, 420, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 421, 422, 423, - 424, 425, 297, 0, 0, 0, 0, 302, 303, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 426, 427, 428, - 429, 430, 431, 432, 433, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 318, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 0, 0, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 0, 0, 414, 415, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 416, 0, 0, 576, 0, - 0, 0, 0, 0, 0, 0, 417, 418, 419, 420, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 421, 422, 423, - 424, 425, 297, 0, 0, 0, 0, 302, 303, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 426, 427, 428, - 429, 430, 431, 432, 433, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 318, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 0, 0, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 0, 0, 414, 415, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 416, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 588, 417, 418, 419, 420, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 421, 422, 423, - 424, 425, 297, 0, 0, 0, 0, 302, 303, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 426, 427, 428, - 429, 430, 431, 432, 433, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 318, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 0, 0, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 0, 0, 414, 415, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 416, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 417, 418, 419, 420, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 421, 422, 423, - 424, 425, 297, 0, 0, 0, 0, 302, 303, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 426, 427, 428, - 429, 430, 431, 432, 433, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 318, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 0, 0, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 0, 0, 414, 415, 0, 444, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 462, 0, 416, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 417, 418, 419, 420, - 528, 529, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 421, 422, 423, - 424, 425, 297, 0, 0, 0, 0, 302, 538, 0, - 0, 541, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 462, 0, 0, 0, 0, 426, 427, 428, - 429, 430, 431, 432, 433, 0, 0, 0, 0, 0, - 0, 462, 0, 0, 318, 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, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 625, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 631, 632, 633, 462, 462, 462, 462, 462, 462, - 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, + 0, 0, 640, 641, 642, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 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, @@ -2333,166 +2368,127 @@ static const yytype_int16 yytable[] = 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, 462 + 471 }; static const yytype_int16 yycheck[] = { - 0, 321, 0, 455, 0, 358, 315, 314, 361, 0, - 363, 364, 321, 333, 367, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 524, 314, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, 292, 341, 349, 416, 378, 506, 518, - 408, 520, 397, 384, 523, 580, 453, 656, 297, 298, - 302, 324, 350, 316, 318, 293, 294, 314, 350, 316, - 374, 324, 316, 370, 405, 406, 323, 299, 300, 316, - 324, 341, 315, 371, 442, 684, 323, 350, 321, 349, - 341, 315, 389, 332, 333, 337, 350, 357, 349, 357, - 360, 357, 351, 295, 296, 316, 357, 356, 357, 695, - 370, 456, 323, 317, 374, 315, 702, 321, 488, 370, - 490, 321, 314, 374, 316, 316, 584, 713, 320, 389, - 475, 318, 323, 315, 321, 315, 315, 324, 389, 321, - 400, 321, 321, 321, 315, 614, 324, 451, 321, 400, - 321, 324, 321, 550, 321, 324, 453, 324, 455, 324, - 518, 321, 520, 533, 324, 523, 304, 305, 306, 307, - 308, 309, 310, 311, 312, 313, 339, 340, 341, 537, - 562, 563, 564, 565, 321, 323, 321, 324, 329, 330, - 331, 451, 717, 453, 326, 455, 328, 655, 667, 319, - 451, 321, 453, 332, 455, 321, 322, 321, 322, 558, - 559, 318, 560, 561, 545, 318, 586, 350, 316, 350, - 590, 618, 566, 567, 350, 324, 323, 524, 350, 315, - 314, 316, 350, 350, 336, 335, 301, 303, 707, 334, - 317, 316, 314, 319, 324, 324, 506, 605, 606, 322, - 314, 314, 314, 550, 324, 506, 614, 324, 314, 314, - 350, 350, 315, 317, 524, 723, 317, 350, 314, 321, - 358, 319, 317, 524, 315, 314, 350, 315, 318, 323, - 650, 324, 315, 318, 362, 319, 656, 318, 324, 568, - 550, 569, 572, 570, 673, 571, 458, 296, 573, 550, - 628, 370, 658, 374, 544, 701, 374, 713, 368, 667, - 714, 658, 684, 516, 684, 516, 675, 516, -1, -1, - 580, 618, -1, -1, 584, 357, 696, -1, 673, 580, - -1, 689, -1, 584, -1, -1, -1, -1, -1, -1, - -1, -1, 712, -1, -1, -1, -1, -1, -1, 707, - -1, -1, -1, -1, -1, -1, -1, -1, 618, 656, - -1, -1, -1, -1, -1, -1, -1, 618, -1, -1, - -1, -1, -1, -1, -1, 679, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 684, -1, -1, - -1, -1, -1, -1, -1, 655, 656, -1, 658, -1, - -1, -1, -1, -1, 655, 656, -1, 658, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 679, - -1, -1, -1, -1, 684, -1, -1, -1, 679, -1, - -1, -1, -1, 684, -1, 695, -1, -1, -1, -1, - -1, -1, 702, -1, 695, -1, -1, -1, -1, -1, - -1, 702, -1, 713, -1, -1, -1, 717, -1, -1, - -1, -1, 713, 723, -1, -1, 717, -1, -1, -1, - 0, -1, 723, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, - 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, - 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, -1, -1, -1, -1, -1, -1, -1, + 0, 324, 0, 317, 0, 319, 319, 319, 464, 0, + 319, 319, 326, 336, 327, 327, 317, 326, 326, 317, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 533, 327, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, + 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, + 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, + 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, + 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, + 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, + 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, + 294, 357, 349, 416, 425, 589, 527, 515, 529, 405, + 321, 532, 462, 386, 353, 299, 300, 304, 665, 392, + 295, 296, 319, 297, 298, 318, 382, 361, 327, 326, + 364, 378, 366, 367, 324, 374, 370, 327, 451, 349, + 413, 414, 353, 317, 324, 319, 693, 357, 349, 323, + 397, 335, 336, 340, 353, 365, 357, 365, 368, 365, + 354, 318, 301, 302, 365, 359, 360, 324, 378, 465, + 320, 353, 382, 704, 324, 335, 497, 378, 499, 324, + 711, 382, 327, 321, 318, 593, 324, 397, 484, 327, + 324, 722, 321, 318, 318, 318, 397, 318, 408, 324, + 324, 324, 623, 324, 460, 318, 322, 408, 324, 559, + 324, 324, 353, 327, 527, 462, 529, 464, 329, 532, + 331, 542, 321, 306, 307, 308, 309, 310, 311, 312, + 313, 314, 315, 546, 571, 572, 573, 574, 324, 324, + 325, 327, 726, 326, 324, 324, 353, 327, 327, 353, + 460, 319, 462, 327, 464, 676, 664, 324, 325, 460, + 326, 462, 353, 464, 342, 343, 344, 332, 333, 334, + 567, 568, 575, 576, 595, 569, 570, 627, 599, 318, + 317, 554, 353, 319, 353, 339, 533, 338, 337, 303, + 305, 320, 319, 317, 322, 716, 327, 327, 317, 317, + 317, 614, 615, 325, 327, 515, 327, 317, 317, 353, + 623, 353, 559, 318, 515, 353, 320, 320, 324, 317, + 361, 320, 322, 533, 732, 318, 317, 353, 318, 321, + 326, 318, 533, 327, 577, 321, 321, 578, 659, 327, + 365, 322, 579, 581, 665, 580, 582, 682, 382, 559, + 382, 298, 467, 553, 637, 667, 710, 722, 559, 723, + 667, 525, 378, 676, 376, 693, 525, 525, 365, 684, + -1, -1, 693, -1, -1, -1, -1, -1, -1, 589, + 627, -1, -1, 593, 705, 698, 682, -1, 589, -1, + -1, -1, 593, -1, -1, -1, -1, -1, -1, -1, + 721, -1, -1, 716, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 627, 665, -1, + -1, -1, -1, -1, -1, -1, 627, -1, -1, -1, + -1, -1, 688, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 693, -1, -1, -1, + -1, -1, -1, -1, 664, 665, -1, 667, -1, -1, + -1, -1, -1, 664, 665, -1, 667, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 688, -1, + -1, -1, -1, 693, -1, -1, -1, 688, -1, -1, + -1, -1, 693, -1, 704, -1, -1, -1, -1, -1, + -1, 711, -1, 704, -1, -1, -1, -1, -1, -1, + 711, -1, 722, -1, -1, -1, 726, -1, -1, -1, + -1, 722, 732, -1, -1, 726, -1, -1, -1, 0, + -1, 732, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, + 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, + 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, + 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, + 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, + 291, 292, 293, 294, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 324, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 338, 339, - 340, 341, 342, -1, -1, -1, -1, -1, -1, -1, - -1, 351, 352, 353, 354, 355, 356, 357, -1, -1, + -1, -1, -1, -1, -1, -1, 327, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 370, 371, 372, 373, 374, 375, -1, -1, -1, -1, - -1, -1, -1, -1, 384, -1, 386, 387, 388, 389, - 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, - 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, - 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, - 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, - 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, - 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, - 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, - 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, - 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, - 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, - 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, - 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - 292, -1, -1, 295, 296, -1, -1, -1, -1, -1, + 341, 342, 343, 344, 345, -1, -1, -1, -1, -1, + -1, -1, -1, 354, 355, 356, 357, 358, 359, 360, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 314, -1, 316, -1, 318, 319, -1, -1, - -1, -1, 324, 325, 326, 327, 328, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 338, 339, 340, 341, - 342, -1, -1, -1, 346, 347, 348, 349, 350, 351, - 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, - -1, 363, 364, 365, 366, 367, 368, 369, 370, 371, - 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, - 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 3, + -1, -1, 373, 374, 375, 376, 377, 378, -1, -1, + -1, -1, -1, -1, -1, -1, 387, -1, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 414, 415, 416, 417, 418, 419, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, @@ -2521,101 +2517,62 @@ static const yytype_int16 yycheck[] = 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, 292, -1, - -1, 295, 296, -1, -1, -1, -1, -1, -1, -1, + 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, + 294, -1, -1, 297, 298, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 314, -1, 316, -1, 318, 319, -1, -1, -1, -1, - 324, 325, 326, 327, 328, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 338, 339, 340, 341, 342, -1, - -1, -1, 346, 347, 348, 349, 350, 351, 352, 353, - 354, 355, 356, 357, 358, 359, 360, 361, -1, 363, - 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, + -1, -1, 316, 317, -1, 319, -1, 321, 322, -1, + -1, -1, -1, 327, 328, 329, 330, 331, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 341, 342, 343, + 344, 345, -1, -1, -1, 349, 350, 351, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, + 364, -1, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, - 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, - 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, -1, -1, 295, - 296, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 314, -1, - 316, -1, 318, -1, -1, -1, -1, -1, 324, 325, - 326, 327, 328, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 338, 339, 340, 341, 342, -1, -1, -1, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 357, 358, 359, 360, 361, -1, 363, 364, 365, - 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, - 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, - 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, - 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, - 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 289, 290, 291, 292, -1, -1, 295, 296, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 314, -1, 316, -1, - 318, -1, -1, -1, -1, -1, 324, 325, 326, 327, - 328, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 338, 339, 340, 341, 342, -1, -1, -1, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, - 358, 359, 360, 361, -1, 363, 364, 365, 366, 367, - 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, - 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 3, 4, 5, 6, 7, 8, 9, + 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, + 414, 415, 416, 417, 418, 419, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, -1, -1, + 297, 298, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 316, + 317, -1, 319, -1, 321, 322, -1, -1, -1, -1, + 327, 328, 329, 330, 331, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 341, 342, 343, 344, 345, -1, + -1, -1, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, -1, 366, + 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, + 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, + 417, 418, 419, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, @@ -2644,100 +2601,61 @@ static const yytype_int16 yycheck[] = 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, -1, -1, 295, 296, -1, -1, -1, + 290, 291, 292, 293, 294, -1, -1, 297, 298, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 314, -1, 316, -1, -1, -1, - -1, -1, -1, -1, 324, 325, 326, 327, 328, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 338, 339, - 340, 341, 342, -1, -1, -1, 346, 347, 348, 349, + -1, -1, -1, -1, -1, -1, 316, 317, -1, 319, + -1, 321, -1, -1, -1, -1, -1, 327, 328, 329, + 330, 331, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 341, 342, 343, 344, 345, -1, -1, -1, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, - 360, 361, -1, 363, 364, 365, 366, 367, 368, 369, + 360, 361, 362, 363, 364, -1, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, - 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, - 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, - 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, - 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, - 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, - 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, - 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, - 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, - 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, - 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, - 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - 292, -1, -1, 295, 296, -1, -1, -1, -1, -1, + 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, + 293, 294, -1, -1, 297, 298, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 314, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 324, 325, 326, 327, 328, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 338, 339, 340, 341, - 342, -1, -1, -1, 346, 347, 348, 349, 350, 351, - 352, 353, 354, 355, 356, 357, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 370, 371, - 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, - 382, 383, 384, -1, 386, 387, 388, 389, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, - 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, - 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, - 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, - 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, - 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, - 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, - 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, - 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, - 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, - 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, 292, -1, - -1, 295, 296, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 314, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 325, 326, 327, 328, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 338, 339, 340, 341, -1, -1, - -1, -1, 346, 347, 348, 349, 350, 351, 352, 353, - 354, 355, 356, 357, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 370, 371, 372, 373, - 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, - 384, -1, 386, 387, 388, 389, 390, 391, 392, 393, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 3, 4, 5, + -1, -1, -1, 316, 317, -1, 319, -1, 321, -1, + -1, -1, -1, -1, 327, 328, 329, 330, 331, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 341, 342, + 343, 344, 345, -1, -1, -1, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, -1, 366, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, + 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, + 413, 414, 415, 416, 417, 418, 419, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, @@ -2766,19 +2684,145 @@ static const yytype_int16 yycheck[] = 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, -1, -1, -1, + 286, 287, 288, 289, 290, 291, 292, 293, 294, -1, + -1, 297, 298, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 324, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 338, 339, 340, 341, 342, -1, -1, -1, - -1, -1, -1, -1, -1, 351, 352, 353, 354, 355, - 356, 357, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 370, 371, 372, 373, 374, 375, - -1, -1, -1, -1, -1, -1, -1, -1, 384, -1, + 316, 317, -1, 319, -1, -1, -1, -1, -1, -1, + -1, 327, 328, 329, 330, 331, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 341, 342, 343, 344, 345, + -1, -1, -1, 349, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, -1, + 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 3, 4, 5, 6, 7, + 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, + 416, 417, 418, 419, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, -1, -1, 297, 298, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 316, 317, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 327, 328, + 329, 330, 331, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 341, 342, 343, 344, 345, -1, -1, -1, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 373, 374, 375, 376, 377, 378, + 379, 380, 381, 382, 383, 384, 385, 386, 387, -1, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, + 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, + 419, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, + 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, + 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + 292, 293, 294, -1, -1, 297, 298, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 316, 317, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 328, 329, 330, 331, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 341, + 342, 343, 344, -1, -1, -1, -1, 349, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 373, 374, 375, 376, 377, 378, 379, 380, 381, + 382, 383, 384, 385, 386, 387, -1, 389, 390, 391, + 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, + 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, + 412, 413, 414, 415, 416, 417, 418, 419, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 327, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 341, 342, 343, 344, + 345, -1, -1, -1, -1, -1, -1, -1, -1, 354, + 355, 356, 357, 358, 359, 360, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 373, 374, + 375, 376, 377, 378, -1, -1, -1, -1, -1, -1, + -1, -1, 387, -1, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 415, 416, 417, 418, 419, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, @@ -2807,100 +2851,61 @@ static const yytype_int16 yycheck[] = 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 289, 290, 291, 292, -1, -1, -1, -1, -1, + 288, 289, 290, 291, 292, 293, 294, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 324, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 327, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 338, 339, 340, 341, -1, -1, -1, -1, -1, -1, - -1, -1, 350, 351, 352, 353, 354, 355, 356, 357, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 370, 371, 372, 373, 374, 375, -1, -1, - -1, -1, -1, -1, -1, -1, 384, -1, 386, 387, - 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + -1, -1, -1, 341, 342, 343, 344, -1, -1, -1, + -1, -1, -1, -1, -1, 353, 354, 355, 356, 357, + 358, 359, 360, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 373, 374, 375, 376, 377, + 378, -1, -1, -1, -1, -1, -1, -1, -1, 387, + -1, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, - 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, - 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, -1, -1, -1, -1, -1, -1, -1, + 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, + 418, 419, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, + 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, + 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, + 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, + 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, + 291, 292, 293, 294, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 319, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 338, 339, - 340, 341, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 351, 352, 353, 354, 355, 356, 357, -1, -1, + -1, 322, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 370, 371, 372, 373, 374, 375, -1, -1, -1, -1, - -1, -1, -1, -1, 384, -1, 386, 387, 388, 389, - 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, - 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, - 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, - 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, - 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, - 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, - 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, - 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, - 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, - 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, - 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, - 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - 292, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 341, 342, 343, 344, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 354, 355, 356, 357, 358, 359, 360, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 319, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 338, 339, 340, 341, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 351, - 352, 353, 354, 355, 356, 357, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 370, 371, - 372, 373, 374, 375, -1, -1, -1, -1, -1, -1, - -1, -1, 384, -1, 386, 387, 388, 389, 390, 391, - 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 3, + -1, -1, 373, 374, 375, 376, 377, 378, -1, -1, + -1, -1, -1, -1, -1, -1, 387, -1, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 414, 415, 416, 417, 418, 419, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, @@ -2929,25 +2934,149 @@ static const yytype_int16 yycheck[] = 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, 292, -1, + 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, + 294, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 322, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 319, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 338, 339, 340, 341, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 351, 352, 353, - 354, 355, 356, 357, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 370, 371, 372, 373, - 374, 375, -1, -1, -1, -1, -1, -1, -1, -1, - 384, -1, 386, 387, 388, 389, 390, 391, 392, 393, + -1, -1, -1, -1, -1, -1, -1, 341, 342, 343, + 344, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 354, 355, 356, 357, 358, 359, 360, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 373, + 374, 375, 376, 377, 378, -1, -1, -1, -1, -1, + -1, -1, -1, 387, -1, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 3, 4, 5, + 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, + 414, 415, 416, 417, 418, 419, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 322, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 341, 342, 343, 344, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 354, 355, 356, + 357, 358, 359, 360, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 373, 374, 375, 376, + 377, 378, -1, -1, -1, -1, -1, -1, -1, -1, + 387, -1, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, + 417, 418, 419, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, + 290, 291, 292, 293, 294, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 341, 342, 343, 344, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 354, 355, 356, 357, 358, 359, + 360, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 373, 374, 375, 376, 377, 378, -1, + -1, -1, -1, -1, -1, -1, -1, 387, -1, 389, + 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, + 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, + 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, -1, -1, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, + 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, + 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, + 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, + 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, + 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, + 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, + 294, -1, -1, 297, 298, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 316, 317, -1, -1, -1, 321, 322, -1, + -1, -1, -1, -1, 328, 329, 330, 331, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 349, 350, 351, 352, 353, + 354, -1, -1, -1, -1, 359, 360, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 379, 380, 381, 382, 383, + 384, 385, 386, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 401, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 56, 57, 58, 59, 60, -1, -1, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, @@ -2970,301 +3099,226 @@ static const yytype_int16 yycheck[] = 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, -1, -1, -1, + 286, 287, 288, 289, 290, 291, 292, 293, 294, -1, + -1, 297, 298, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 316, 317, -1, -1, 320, -1, -1, -1, -1, -1, + -1, -1, 328, 329, 330, 331, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 349, 350, 351, 352, 353, 354, -1, + -1, -1, -1, 359, 360, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 379, 380, 381, 382, 383, 384, 385, + 386, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 401, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, -1, -1, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 293, 294, -1, -1, 297, + 298, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 316, 317, + -1, -1, -1, 321, -1, -1, -1, -1, -1, -1, + 328, 329, 330, 331, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 349, 350, 351, 352, 353, 354, -1, -1, -1, + -1, 359, 360, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 379, 380, 381, 382, 383, 384, 385, 386, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 401, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, -1, -1, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, + 290, 291, 292, 293, 294, -1, -1, 297, 298, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 316, 317, -1, -1, + 320, -1, -1, -1, -1, -1, -1, -1, 328, 329, + 330, 331, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 349, + 350, 351, 352, 353, 354, -1, -1, -1, -1, 359, + 360, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 379, + 380, 381, 382, 383, 384, 385, 386, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 401, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, -1, + -1, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, + 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, + 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + 292, 293, 294, -1, -1, 297, 298, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 316, 317, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 327, 328, 329, 330, 331, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 349, 350, 351, + 352, 353, 354, -1, -1, -1, -1, 359, 360, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 379, 380, 381, + 382, 383, 384, 385, 386, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 401, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, -1, -1, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, + 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, + 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, + 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, + 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, + 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, + 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, + 294, -1, -1, 297, 298, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 316, 317, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 328, 329, 330, 331, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 349, 350, 351, 352, 353, + 354, -1, -1, -1, -1, 359, 360, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 379, 380, 381, 382, 383, + 384, 385, 386, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 401, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, -1, -1, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, + 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, + 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, + 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, + 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, + 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, + 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, + 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 286, 287, 288, 289, 290, 291, 292, 293, 294, 391, + -1, 297, 298, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 405, -1, -1, -1, -1, -1, -1, + 316, 317, -1, -1, -1, -1, -1, -1, -1, -1, + 422, 423, 328, 329, 330, 331, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 349, 350, 351, 352, 353, 354, -1, + -1, -1, 454, 359, 360, -1, -1, -1, -1, -1, + -1, -1, -1, 465, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 379, 380, 381, 382, 383, 384, 385, + 386, -1, 484, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 401, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 338, 339, 340, 341, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 351, 352, 353, 354, 355, - 356, 357, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 370, 371, 372, 373, 374, 375, - -1, -1, -1, -1, -1, -1, -1, -1, 384, -1, - 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, -1, -1, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, 292, -1, -1, 295, 296, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 551, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 314, -1, -1, -1, 318, - 319, -1, -1, -1, -1, -1, 325, 326, 327, 328, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 346, 347, 348, - 349, 350, 351, -1, -1, -1, -1, 356, 357, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 376, 377, 378, - 379, 380, 381, 382, 383, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 393, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, -1, -1, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, 292, -1, -1, 295, 296, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 314, -1, -1, 317, -1, - -1, -1, -1, -1, -1, -1, 325, 326, 327, 328, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 346, 347, 348, - 349, 350, 351, -1, -1, -1, -1, 356, 357, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 376, 377, 378, - 379, 380, 381, 382, 383, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 393, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, -1, -1, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, 292, -1, -1, 295, 296, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 314, -1, -1, -1, 318, - -1, -1, -1, -1, -1, -1, 325, 326, 327, 328, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 346, 347, 348, - 349, 350, 351, -1, -1, -1, -1, 356, 357, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 376, 377, 378, - 379, 380, 381, 382, 383, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 393, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, -1, -1, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, 292, -1, -1, 295, 296, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 314, -1, -1, 317, -1, - -1, -1, -1, -1, -1, -1, 325, 326, 327, 328, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 346, 347, 348, - 349, 350, 351, -1, -1, -1, -1, 356, 357, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 376, 377, 378, - 379, 380, 381, 382, 383, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 393, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, -1, -1, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, 292, -1, -1, 295, 296, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 314, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 324, 325, 326, 327, 328, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 346, 347, 348, - 349, 350, 351, -1, -1, -1, -1, 356, 357, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 376, 377, 378, - 379, 380, 381, 382, 383, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 393, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, -1, -1, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, 292, -1, -1, 295, 296, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 314, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 325, 326, 327, 328, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 346, 347, 348, - 349, 350, 351, -1, -1, -1, -1, 356, 357, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 376, 377, 378, - 379, 380, 381, 382, 383, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 393, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, -1, -1, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, 292, -1, -1, 295, 296, -1, 383, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 397, -1, 314, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 325, 326, 327, 328, - 414, 415, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 346, 347, 348, - 349, 350, 351, -1, -1, -1, -1, 356, 357, -1, - -1, 445, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 456, -1, -1, -1, -1, 376, 377, 378, - 379, 380, 381, 382, 383, -1, -1, -1, -1, -1, - -1, 475, -1, -1, 393, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 542, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 555, 556, 557, 558, 559, 560, 561, 562, 563, - 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, + -1, -1, 564, 565, 566, 567, 568, 569, 570, 571, + 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, + 582, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, @@ -3274,7 +3328,7 @@ static const yytype_int16 yycheck[] = -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 673 + 682 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -3310,139 +3364,142 @@ static const yytype_uint16 yystos[] = 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - 292, 324, 338, 339, 340, 341, 342, 351, 352, 353, - 354, 355, 356, 357, 370, 371, 372, 373, 374, 375, - 384, 386, 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 442, 443, 446, 447, - 448, 449, 453, 454, 455, 456, 457, 458, 461, 462, - 463, 464, 465, 467, 472, 473, 474, 515, 516, 517, - 473, 318, 350, 314, 314, 324, 350, 324, 518, 315, - 321, 450, 451, 452, 462, 467, 321, 324, 350, 324, - 350, 463, 467, 332, 469, 470, 0, 516, 467, 476, - 318, 350, 371, 459, 460, 350, 466, 316, 324, 468, - 318, 494, 451, 450, 452, 350, 350, 314, 323, 468, - 318, 321, 324, 445, 295, 296, 314, 325, 326, 327, - 328, 346, 347, 348, 349, 350, 376, 377, 378, 379, - 380, 381, 382, 383, 412, 413, 414, 416, 417, 418, - 419, 420, 421, 422, 423, 424, 465, 467, 471, 468, - 324, 462, 467, 477, 478, 475, 323, 315, 321, 315, - 321, 317, 423, 425, 426, 427, 428, 429, 430, 431, - 432, 433, 434, 435, 436, 316, 324, 316, 318, 319, - 324, 358, 359, 360, 361, 363, 364, 365, 366, 367, - 368, 369, 385, 423, 436, 438, 440, 442, 446, 465, - 467, 483, 484, 485, 486, 487, 495, 496, 497, 498, - 501, 502, 505, 506, 507, 514, 519, 468, 323, 468, - 318, 438, 481, 323, 444, 350, 321, 324, 423, 423, - 440, 295, 296, 316, 320, 315, 315, 321, 357, 438, - 314, 423, 321, 333, 467, 350, 479, 480, 319, 478, - 477, 436, 441, 460, 350, 329, 330, 331, 326, 328, - 293, 294, 297, 298, 332, 333, 299, 300, 336, 335, - 334, 301, 303, 302, 337, 317, 317, 436, 316, 319, - 488, 314, 324, 324, 509, 314, 314, 324, 324, 440, - 314, 440, 322, 324, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 323, 439, 321, 324, 319, 484, - 498, 502, 507, 481, 323, 481, 482, 481, 477, 350, - 315, 415, 440, 350, 438, 423, 479, 468, 321, 324, - 319, 423, 423, 423, 425, 425, 426, 426, 427, 427, - 427, 427, 428, 428, 429, 430, 431, 432, 433, 434, - 437, 317, 350, 520, 521, 495, 508, 484, 510, 440, - 324, 440, 322, 438, 438, 481, 319, 321, 319, 317, - 324, 480, 440, 314, 317, 321, 489, 440, 455, 462, - 500, 358, 483, 496, 511, 315, 315, 319, 481, 322, - 441, 317, 521, 319, 350, 315, 314, 500, 512, 513, - 491, 492, 493, 499, 503, 438, 315, 323, 485, 490, - 494, 440, 324, 315, 362, 487, 485, 318, 481, 315, - 440, 490, 491, 495, 504, 324, 319 + 292, 293, 294, 327, 341, 342, 343, 344, 345, 354, + 355, 356, 357, 358, 359, 360, 373, 374, 375, 376, + 377, 378, 387, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, + 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, + 416, 417, 418, 419, 451, 452, 455, 456, 457, 458, + 462, 463, 464, 465, 466, 467, 470, 471, 472, 473, + 474, 476, 481, 482, 483, 524, 525, 526, 482, 321, + 353, 317, 317, 327, 353, 327, 527, 318, 324, 459, + 460, 461, 471, 476, 324, 327, 353, 327, 353, 472, + 476, 335, 478, 479, 0, 525, 476, 485, 321, 353, + 374, 468, 469, 353, 475, 319, 327, 477, 321, 503, + 460, 459, 461, 353, 353, 317, 326, 477, 321, 324, + 327, 454, 297, 298, 316, 317, 328, 329, 330, 331, + 349, 350, 351, 352, 353, 379, 380, 381, 382, 383, + 384, 385, 386, 421, 422, 423, 425, 426, 427, 428, + 429, 430, 431, 432, 433, 474, 476, 480, 477, 327, + 471, 476, 486, 487, 484, 326, 318, 324, 318, 324, + 320, 432, 434, 435, 436, 437, 438, 439, 440, 441, + 442, 443, 444, 445, 319, 327, 319, 321, 322, 327, + 361, 362, 363, 364, 366, 367, 368, 369, 370, 371, + 372, 388, 432, 445, 447, 449, 451, 455, 474, 476, + 492, 493, 494, 495, 496, 504, 505, 506, 507, 510, + 511, 514, 515, 516, 523, 528, 477, 326, 477, 321, + 447, 490, 326, 453, 353, 324, 327, 432, 432, 449, + 297, 298, 319, 323, 318, 318, 324, 360, 447, 317, + 432, 324, 336, 476, 353, 488, 489, 322, 487, 486, + 445, 450, 469, 353, 332, 333, 334, 329, 331, 295, + 296, 299, 300, 335, 336, 301, 302, 339, 338, 337, + 303, 305, 304, 340, 320, 320, 445, 319, 322, 497, + 317, 327, 327, 518, 317, 317, 327, 327, 449, 317, + 449, 325, 327, 306, 307, 308, 309, 310, 311, 312, + 313, 314, 315, 326, 448, 324, 327, 322, 493, 507, + 511, 516, 490, 326, 490, 491, 490, 486, 353, 318, + 424, 449, 353, 447, 432, 488, 477, 324, 327, 322, + 432, 432, 432, 434, 434, 435, 435, 436, 436, 436, + 436, 437, 437, 438, 439, 440, 441, 442, 443, 446, + 320, 353, 529, 530, 504, 517, 493, 519, 449, 327, + 449, 325, 447, 447, 490, 322, 324, 322, 320, 327, + 489, 449, 317, 320, 324, 498, 449, 464, 471, 509, + 361, 492, 505, 520, 318, 318, 322, 490, 325, 450, + 320, 530, 322, 353, 318, 317, 509, 521, 522, 500, + 501, 502, 508, 512, 447, 318, 326, 494, 499, 503, + 449, 327, 318, 365, 496, 494, 321, 490, 318, 449, + 499, 500, 504, 513, 327, 322 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint16 yyr1[] = { - 0, 411, 412, 413, 413, 413, 413, 413, 413, 413, - 413, 413, 413, 413, 413, 413, 413, 414, 414, 414, - 414, 414, 414, 415, 416, 417, 418, 418, 419, 419, - 420, 420, 421, 422, 422, 422, 423, 423, 423, 423, - 424, 424, 424, 424, 425, 425, 425, 425, 426, 426, - 426, 427, 427, 427, 428, 428, 428, 428, 428, 429, - 429, 429, 430, 430, 431, 431, 432, 432, 433, 433, - 434, 434, 435, 435, 436, 437, 436, 438, 438, 439, - 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, - 440, 440, 441, 442, 442, 442, 442, 442, 442, 442, - 442, 442, 444, 443, 445, 445, 446, 447, 447, 448, - 448, 449, 450, 450, 451, 451, 451, 451, 452, 453, - 453, 453, 453, 453, 454, 454, 454, 454, 454, 455, - 455, 456, 457, 457, 457, 457, 457, 457, 457, 457, - 458, 459, 459, 460, 460, 460, 461, 462, 462, 463, - 463, 463, 463, 463, 463, 463, 464, 464, 464, 464, - 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, - 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, - 464, 464, 464, 464, 464, 465, 466, 466, 467, 467, - 468, 468, 468, 468, 469, 469, 470, 471, 471, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 472, 472, 472, 473, - 473, 473, 475, 474, 476, 474, 477, 477, 478, 478, - 479, 479, 480, 480, 481, 481, 481, 482, 482, 483, - 484, 484, 485, 485, 485, 485, 485, 485, 485, 485, - 486, 487, 488, 489, 487, 490, 490, 492, 491, 493, - 491, 494, 494, 495, 495, 496, 496, 497, 497, 498, - 499, 499, 500, 500, 501, 501, 503, 502, 504, 504, - 505, 505, 506, 506, 508, 507, 509, 507, 510, 507, - 511, 511, 512, 512, 513, 513, 514, 514, 514, 514, - 514, 515, 515, 516, 516, 516, 518, 517, 519, 520, - 520, 521, 521 + 0, 420, 421, 422, 422, 422, 422, 422, 422, 422, + 422, 422, 422, 422, 422, 422, 422, 422, 423, 423, + 423, 423, 423, 423, 424, 425, 426, 427, 427, 428, + 428, 429, 429, 430, 431, 431, 431, 432, 432, 432, + 432, 433, 433, 433, 433, 434, 434, 434, 434, 435, + 435, 435, 436, 436, 436, 437, 437, 437, 437, 437, + 438, 438, 438, 439, 439, 440, 440, 441, 441, 442, + 442, 443, 443, 444, 444, 445, 446, 445, 447, 447, + 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, + 448, 449, 449, 450, 451, 451, 451, 451, 451, 451, + 451, 451, 451, 453, 452, 454, 454, 455, 456, 456, + 457, 457, 458, 459, 459, 460, 460, 460, 460, 461, + 462, 462, 462, 462, 462, 463, 463, 463, 463, 463, + 464, 464, 465, 466, 466, 466, 466, 466, 466, 466, + 466, 467, 468, 468, 469, 469, 469, 470, 471, 471, + 472, 472, 472, 472, 472, 472, 472, 473, 473, 473, + 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, + 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, + 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, + 473, 473, 474, 475, 475, 476, 476, 477, 477, 477, + 477, 478, 478, 479, 480, 480, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 482, 482, + 482, 484, 483, 485, 483, 486, 486, 487, 487, 488, + 488, 489, 489, 490, 490, 490, 491, 491, 492, 493, + 493, 494, 494, 494, 494, 494, 494, 494, 494, 495, + 496, 497, 498, 496, 499, 499, 501, 500, 502, 500, + 503, 503, 504, 504, 505, 505, 506, 506, 507, 508, + 508, 509, 509, 510, 510, 512, 511, 513, 513, 514, + 514, 515, 515, 517, 516, 518, 516, 519, 516, 520, + 520, 521, 521, 522, 522, 523, 523, 523, 523, 523, + 524, 524, 525, 525, 525, 527, 526, 528, 529, 529, + 530, 530 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 1, 1, 3, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, - 3, 2, 2, 1, 1, 1, 2, 2, 2, 1, - 2, 3, 2, 1, 1, 1, 1, 2, 2, 2, - 1, 1, 1, 1, 1, 3, 3, 3, 1, 3, - 3, 1, 3, 3, 1, 3, 3, 3, 3, 1, - 3, 3, 1, 3, 1, 3, 1, 3, 1, 3, - 1, 3, 1, 3, 1, 0, 6, 1, 3, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, + 1, 3, 2, 2, 1, 1, 1, 2, 2, 2, + 1, 2, 3, 2, 1, 1, 1, 1, 2, 2, + 2, 1, 1, 1, 1, 1, 3, 3, 3, 1, + 3, 3, 1, 3, 3, 1, 3, 3, 3, 3, + 1, 3, 3, 1, 3, 1, 3, 1, 3, 1, + 3, 1, 3, 1, 3, 1, 0, 6, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 3, 1, 2, 2, 4, 2, 3, 4, 2, - 3, 4, 0, 6, 2, 3, 2, 1, 1, 2, - 3, 3, 2, 3, 2, 1, 2, 1, 1, 1, - 3, 4, 6, 5, 1, 2, 3, 5, 4, 1, - 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 4, 1, 3, 1, 3, 1, 1, 1, 2, 1, + 1, 1, 3, 1, 2, 2, 4, 2, 3, 4, + 2, 3, 4, 0, 6, 2, 3, 2, 1, 1, + 2, 3, 3, 2, 3, 2, 1, 2, 1, 1, + 1, 3, 4, 6, 5, 1, 2, 3, 5, 4, + 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 4, 1, 3, 1, 3, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 4, 1, 1, 3, 2, 3, - 2, 3, 3, 4, 1, 0, 3, 1, 3, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 4, 1, 1, 3, 2, 3, 2, 3, 3, + 4, 1, 0, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -3472,16 +3529,16 @@ static const yytype_uint8 yyr2[] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 0, 6, 0, 5, 1, 2, 3, 4, - 1, 3, 1, 2, 1, 3, 4, 1, 3, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 0, 0, 5, 1, 1, 0, 2, 0, - 2, 2, 3, 1, 2, 1, 2, 1, 2, 5, - 3, 1, 1, 4, 1, 2, 0, 8, 0, 1, - 3, 2, 1, 2, 0, 6, 0, 8, 0, 7, - 1, 1, 1, 0, 2, 3, 2, 2, 2, 3, - 2, 1, 2, 1, 1, 1, 0, 3, 5, 1, - 3, 1, 4 + 1, 0, 6, 0, 5, 1, 2, 3, 4, 1, + 3, 1, 2, 1, 3, 4, 1, 3, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 2, 0, 0, 5, 1, 1, 0, 2, 0, 2, + 2, 3, 1, 2, 1, 2, 1, 2, 5, 3, + 1, 1, 4, 1, 2, 0, 8, 0, 1, 3, + 2, 1, 2, 0, 6, 0, 8, 0, 7, 1, + 1, 1, 0, 2, 3, 2, 2, 2, 3, 2, + 1, 2, 1, 1, 1, 0, 3, 5, 1, 3, + 1, 4 }; @@ -4164,252 +4221,260 @@ yyreduce: switch (yyn) { case 2: -#line 352 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 357 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = parseContext.handleVariable((yyvsp[0].lex).loc, (yyvsp[0].lex).symbol, (yyvsp[0].lex).string); } -#line 4172 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4229 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 3: -#line 358 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 363 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4180 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4237 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 4: -#line 361 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 366 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[-1].interm.intermTypedNode); if ((yyval.interm.intermTypedNode)->getAsConstantUnion()) (yyval.interm.intermTypedNode)->getAsConstantUnion()->setExpression(); } -#line 4190 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4247 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 5: -#line 366 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 371 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat, (yyvsp[0].lex).loc, true); } -#line 4198 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4255 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 6: -#line 369 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 374 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); } -#line 4206 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4263 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 7: -#line 372 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 377 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned literal"); (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); } -#line 4215 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4272 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 8: -#line 376 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 381 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).b, (yyvsp[0].lex).loc, true); } -#line 4223 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4280 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 9: -#line 380 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 385 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).string, (yyvsp[0].lex).loc, true); + } +#line 4288 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 10: +#line 388 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed literal"); (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); } -#line 4232 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4297 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 10: -#line 384 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 11: +#line 392 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed literal"); (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); } -#line 4241 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4306 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 11: -#line 388 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 12: +#line 396 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer literal"); (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i64, (yyvsp[0].lex).loc, true); } -#line 4250 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4315 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 12: -#line 392 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 13: +#line 400 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer literal"); (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u64, (yyvsp[0].lex).loc, true); } -#line 4259 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4324 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 13: -#line 396 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 14: +#line 404 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitInt16Check((yyvsp[0].lex).loc, "16-bit integer literal"); (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((short)(yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); } -#line 4268 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4333 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 14: -#line 400 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 15: +#line 408 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitInt16Check((yyvsp[0].lex).loc, "16-bit unsigned integer literal"); (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((unsigned short)(yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); } -#line 4277 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4342 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 15: -#line 404 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 16: +#line 412 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double literal"); if (! parseContext.symbolTable.atBuiltInLevel()) parseContext.doubleCheck((yyvsp[0].lex).loc, "double literal"); (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtDouble, (yyvsp[0].lex).loc, true); } -#line 4286 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4353 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 16: -#line 408 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 17: +#line 418 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16Check((yyvsp[0].lex).loc, "half float literal"); (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat16, (yyvsp[0].lex).loc, true); } -#line 4295 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 17: -#line 416 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); - } -#line 4303 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4362 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 18: -#line 419 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.intermTypedNode) = parseContext.handleBracketDereference((yyvsp[-2].lex).loc, (yyvsp[-3].interm.intermTypedNode), (yyvsp[-1].interm.intermTypedNode)); - } -#line 4311 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 19: -#line 422 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 426 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4319 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4370 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 19: +#line 429 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBracketDereference((yyvsp[-2].lex).loc, (yyvsp[-3].interm.intermTypedNode), (yyvsp[-1].interm.intermTypedNode)); + } +#line 4378 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 20: -#line 425 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 432 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = parseContext.handleDotDereference((yyvsp[0].lex).loc, (yyvsp[-2].interm.intermTypedNode), *(yyvsp[0].lex).string); + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4327 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4386 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 21: -#line 428 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 435 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleDotDereference((yyvsp[0].lex).loc, (yyvsp[-2].interm.intermTypedNode), *(yyvsp[0].lex).string); + } +#line 4394 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 22: +#line 438 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.variableCheck((yyvsp[-1].interm.intermTypedNode)); parseContext.lValueErrorCheck((yyvsp[0].lex).loc, "++", (yyvsp[-1].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[0].lex).loc, "++", EOpPostIncrement, (yyvsp[-1].interm.intermTypedNode)); } -#line 4337 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4404 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 22: -#line 433 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 23: +#line 443 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.variableCheck((yyvsp[-1].interm.intermTypedNode)); parseContext.lValueErrorCheck((yyvsp[0].lex).loc, "--", (yyvsp[-1].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[0].lex).loc, "--", EOpPostDecrement, (yyvsp[-1].interm.intermTypedNode)); } -#line 4347 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4414 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 23: -#line 441 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 24: +#line 451 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.integerCheck((yyvsp[0].interm.intermTypedNode), "[]"); (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4356 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4423 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 24: -#line 448 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 25: +#line 458 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = parseContext.handleFunctionCall((yyvsp[0].interm).loc, (yyvsp[0].interm).function, (yyvsp[0].interm).intermNode); delete (yyvsp[0].interm).function; } -#line 4365 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 25: -#line 455 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm) = (yyvsp[0].interm); - } -#line 4373 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4432 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 26: -#line 461 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm) = (yyvsp[-1].interm); - (yyval.interm).loc = (yyvsp[0].lex).loc; - } -#line 4382 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 27: #line 465 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm) = (yyvsp[-1].interm); - (yyval.interm).loc = (yyvsp[0].lex).loc; - } -#line 4391 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 28: -#line 472 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm) = (yyvsp[-1].interm); - } -#line 4399 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 29: -#line 475 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[0].interm); } -#line 4407 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4440 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 27: +#line 471 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[-1].interm); + (yyval.interm).loc = (yyvsp[0].lex).loc; + } +#line 4449 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 28: +#line 475 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[-1].interm); + (yyval.interm).loc = (yyvsp[0].lex).loc; + } +#line 4458 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 29: +#line 482 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[-1].interm); + } +#line 4466 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 30: -#line 481 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 485 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[0].interm); + } +#line 4474 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 31: +#line 491 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { TParameter param = { 0, new TType }; param.type->shallowCopy((yyvsp[0].interm.intermTypedNode)->getType()); @@ -4417,11 +4482,11 @@ yyreduce: (yyval.interm).function = (yyvsp[-1].interm).function; (yyval.interm).intermNode = (yyvsp[0].interm.intermTypedNode); } -#line 4419 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4486 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 31: -#line 488 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 32: +#line 498 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { TParameter param = { 0, new TType }; param.type->shallowCopy((yyvsp[0].interm.intermTypedNode)->getType()); @@ -4429,29 +4494,29 @@ yyreduce: (yyval.interm).function = (yyvsp[-2].interm).function; (yyval.interm).intermNode = parseContext.intermediate.growAggregate((yyvsp[-2].interm).intermNode, (yyvsp[0].interm.intermTypedNode), (yyvsp[-1].lex).loc); } -#line 4431 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 32: -#line 498 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm) = (yyvsp[-1].interm); - } -#line 4439 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4498 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 33: -#line 506 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 508 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[-1].interm); + } +#line 4506 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 34: +#line 516 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // Constructor (yyval.interm).intermNode = 0; (yyval.interm).function = parseContext.handleConstructorCall((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type)); } -#line 4449 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4516 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 34: -#line 511 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 35: +#line 521 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // // Should be a method or subroutine call, but we haven't recognized the arguments yet. @@ -4479,50 +4544,50 @@ yyreduce: (yyval.interm).function = new TFunction(empty, TType(EbtVoid), EOpNull); } } -#line 4481 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4548 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 35: -#line 539 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 36: +#line 549 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // Constructor (yyval.interm).intermNode = 0; (yyval.interm).function = parseContext.handleConstructorCall((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type)); } -#line 4491 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4558 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 36: -#line 548 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 37: +#line 558 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.variableCheck((yyvsp[0].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); if (TIntermMethod* method = (yyvsp[0].interm.intermTypedNode)->getAsMethodNode()) parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "incomplete method syntax", method->getMethodName().c_str(), ""); } -#line 4502 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4569 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 37: -#line 554 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 38: +#line 564 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.lValueErrorCheck((yyvsp[-1].lex).loc, "++", (yyvsp[0].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[-1].lex).loc, "++", EOpPreIncrement, (yyvsp[0].interm.intermTypedNode)); } -#line 4511 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4578 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 38: -#line 558 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 39: +#line 568 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.lValueErrorCheck((yyvsp[-1].lex).loc, "--", (yyvsp[0].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[-1].lex).loc, "--", EOpPreDecrement, (yyvsp[0].interm.intermTypedNode)); } -#line 4520 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4587 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 39: -#line 562 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 40: +#line 572 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if ((yyvsp[-1].interm).op != EOpNull) { char errorOp[2] = {0, 0}; @@ -4539,179 +4604,179 @@ yyreduce: (yyval.interm.intermTypedNode)->getAsConstantUnion()->setExpression(); } } -#line 4541 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 40: -#line 582 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpNull; } -#line 4547 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4608 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 41: -#line 583 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpNegative; } -#line 4553 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 592 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpNull; } +#line 4614 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 42: -#line 584 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpLogicalNot; } -#line 4559 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 593 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpNegative; } +#line 4620 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 43: -#line 585 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpBitwiseNot; - parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise not"); } -#line 4566 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 594 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpLogicalNot; } +#line 4626 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 44: -#line 591 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4572 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 595 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpBitwiseNot; + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise not"); } +#line 4633 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 45: -#line 592 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 601 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4639 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 46: +#line 602 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "*", EOpMul, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 4582 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4649 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 46: -#line 597 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 47: +#line 607 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "/", EOpDiv, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 4592 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4659 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 47: -#line 602 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 48: +#line 612 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "%"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "%", EOpMod, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 4603 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 48: -#line 611 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4609 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4670 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 49: -#line 612 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 621 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4676 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 50: +#line 622 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "+", EOpAdd, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 4619 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4686 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 50: -#line 617 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 51: +#line 627 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "-", EOpSub, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 4629 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 51: -#line 625 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4635 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4696 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 52: -#line 626 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 635 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4702 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 53: +#line 636 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bit shift left"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "<<", EOpLeftShift, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 4646 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4713 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 53: -#line 632 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 54: +#line 642 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bit shift right"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, ">>", EOpRightShift, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 4657 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 54: -#line 641 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4663 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4724 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 55: -#line 642 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 651 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4730 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 56: +#line 652 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "<", EOpLessThan, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 4673 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4740 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 56: -#line 647 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 57: +#line 657 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, ">", EOpGreaterThan, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 4683 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4750 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 57: -#line 652 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 58: +#line 662 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "<=", EOpLessThanEqual, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 4693 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4760 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 58: -#line 657 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 59: +#line 667 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, ">=", EOpGreaterThanEqual, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 4703 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 59: -#line 665 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4709 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4770 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 60: -#line 666 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 675 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4776 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 61: +#line 676 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.arrayObjectCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "array comparison"); parseContext.opaqueCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "=="); @@ -4721,11 +4786,11 @@ yyreduce: if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 4723 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4790 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 61: -#line 675 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 62: +#line 685 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.arrayObjectCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "array comparison"); parseContext.opaqueCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "!="); @@ -4735,124 +4800,124 @@ yyreduce: if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 4737 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 62: -#line 687 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4743 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4804 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 63: -#line 688 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 697 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4810 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 64: +#line 698 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bitwise and"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "&", EOpAnd, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 4754 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 64: -#line 697 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4760 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4821 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 65: -#line 698 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 707 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4827 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 66: +#line 708 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bitwise exclusive or"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "^", EOpExclusiveOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 4771 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 66: -#line 707 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4777 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4838 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 67: -#line 708 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 717 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4844 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 68: +#line 718 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bitwise inclusive or"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "|", EOpInclusiveOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 4788 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 68: -#line 717 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4794 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4855 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 69: -#line 718 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 727 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4861 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 70: +#line 728 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "&&", EOpLogicalAnd, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 4804 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 70: -#line 726 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4810 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4871 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 71: -#line 727 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 736 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4877 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 72: +#line 737 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "^^", EOpLogicalXor, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 4820 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 72: -#line 735 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4826 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4887 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 73: -#line 736 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 745 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4893 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 74: +#line 746 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "||", EOpLogicalOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 4836 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 74: -#line 744 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4842 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4903 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 75: -#line 745 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - ++parseContext.controlFlowNestingLevel; - } -#line 4850 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 754 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4909 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 76: -#line 748 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 755 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + ++parseContext.controlFlowNestingLevel; + } +#line 4917 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 77: +#line 758 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { --parseContext.controlFlowNestingLevel; parseContext.boolCheck((yyvsp[-4].lex).loc, (yyvsp[-5].interm.intermTypedNode)); @@ -4865,17 +4930,17 @@ yyreduce: (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } } -#line 4867 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 77: -#line 763 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4873 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4934 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 78: -#line 764 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 773 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4940 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 79: +#line 774 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.arrayObjectCheck((yyvsp[-1].interm).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "array assignment"); parseContext.opaqueCheck((yyvsp[-1].interm).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "="); @@ -4883,125 +4948,125 @@ yyreduce: parseContext.specializationCheck((yyvsp[-1].interm).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "="); parseContext.lValueErrorCheck((yyvsp[-1].interm).loc, "assign", (yyvsp[-2].interm.intermTypedNode)); parseContext.rValueErrorCheck((yyvsp[-1].interm).loc, "assign", (yyvsp[0].interm.intermTypedNode)); - (yyval.interm.intermTypedNode) = parseContext.intermediate.addAssign((yyvsp[-1].interm).op, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yyvsp[-1].interm).loc); + (yyval.interm.intermTypedNode) = parseContext.addAssign((yyvsp[-1].interm).loc, (yyvsp[-1].interm).op, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) { parseContext.assignError((yyvsp[-1].interm).loc, "assign", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(), (yyvsp[0].interm.intermTypedNode)->getCompleteString()); (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } } -#line 4891 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4958 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 79: -#line 780 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 80: +#line 790 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpAssign; } -#line 4900 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4967 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 80: -#line 784 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 81: +#line 794 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpMulAssign; } -#line 4909 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4976 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 81: -#line 788 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 82: +#line 798 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpDivAssign; } -#line 4918 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4985 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 82: -#line 792 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 83: +#line 802 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "%="); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpModAssign; } -#line 4928 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4995 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 83: -#line 797 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 84: +#line 807 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpAddAssign; } -#line 4937 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5004 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 84: -#line 801 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 85: +#line 811 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpSubAssign; } -#line 4946 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5013 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 85: -#line 805 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 86: +#line 815 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bit-shift left assign"); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpLeftShiftAssign; } -#line 4955 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5022 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 86: -#line 809 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 87: +#line 819 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bit-shift right assign"); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpRightShiftAssign; } -#line 4964 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5031 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 87: -#line 813 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 88: +#line 823 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise-and assign"); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpAndAssign; } -#line 4973 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5040 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 88: -#line 817 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 89: +#line 827 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise-xor assign"); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpExclusiveOrAssign; } -#line 4982 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5049 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 89: -#line 821 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 90: +#line 831 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise-or assign"); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpInclusiveOrAssign; } -#line 4991 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 90: -#line 828 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); - } -#line 4999 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5058 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 91: -#line 831 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 838 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + } +#line 5066 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 92: +#line 841 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.samplerConstructorLocationCheck((yyvsp[-1].lex).loc, ",", (yyvsp[0].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = parseContext.intermediate.addComma((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yyvsp[-1].lex).loc); @@ -5010,40 +5075,40 @@ yyreduce: (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } } -#line 5012 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5079 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 92: -#line 842 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 93: +#line 852 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.constantValueCheck((yyvsp[0].interm.intermTypedNode), ""); (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5021 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5088 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 93: -#line 849 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 94: +#line 859 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.handleFunctionDeclarator((yyvsp[-1].interm).loc, *(yyvsp[-1].interm).function, true /* prototype */); (yyval.interm.intermNode) = 0; // TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature } -#line 5031 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5098 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 94: -#line 854 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 95: +#line 864 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if ((yyvsp[-1].interm).intermNode && (yyvsp[-1].interm).intermNode->getAsAggregate()) (yyvsp[-1].interm).intermNode->getAsAggregate()->setOperator(EOpSequence); (yyval.interm.intermNode) = (yyvsp[-1].interm).intermNode; } -#line 5041 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5108 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 95: -#line 859 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 96: +#line 869 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.profileRequires((yyvsp[-3].lex).loc, ENoProfile, 130, 0, "precision statement"); // lazy setting of the previous scope's defaults, has effect only the first time it is called in a particular scope @@ -5051,75 +5116,75 @@ yyreduce: parseContext.setDefaultPrecision((yyvsp[-3].lex).loc, (yyvsp[-1].interm.type), (yyvsp[-2].interm.type).qualifier.precision); (yyval.interm.intermNode) = 0; } -#line 5053 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5120 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 96: -#line 866 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 97: +#line 876 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.declareBlock((yyvsp[-1].interm).loc, *(yyvsp[-1].interm).typeList); (yyval.interm.intermNode) = 0; } -#line 5062 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5129 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 97: -#line 870 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 98: +#line 880 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.declareBlock((yyvsp[-2].interm).loc, *(yyvsp[-2].interm).typeList, (yyvsp[-1].lex).string); (yyval.interm.intermNode) = 0; } -#line 5071 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5138 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 98: -#line 874 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 99: +#line 884 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.declareBlock((yyvsp[-3].interm).loc, *(yyvsp[-3].interm).typeList, (yyvsp[-2].lex).string, (yyvsp[-1].interm).arraySizes); (yyval.interm.intermNode) = 0; } -#line 5080 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5147 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 99: -#line 878 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 100: +#line 888 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalQualifierFixCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier); parseContext.updateStandaloneQualifierDefaults((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type)); (yyval.interm.intermNode) = 0; } -#line 5090 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5157 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 100: -#line 883 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 101: +#line 893 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.checkNoShaderLayouts((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).shaderQualifiers); parseContext.addQualifierToExisting((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).qualifier, *(yyvsp[-1].lex).string); (yyval.interm.intermNode) = 0; } -#line 5100 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5167 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 101: -#line 888 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 102: +#line 898 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.checkNoShaderLayouts((yyvsp[-3].interm.type).loc, (yyvsp[-3].interm.type).shaderQualifiers); (yyvsp[-1].interm.identifierList)->push_back((yyvsp[-2].lex).string); parseContext.addQualifierToExisting((yyvsp[-3].interm.type).loc, (yyvsp[-3].interm.type).qualifier, *(yyvsp[-1].interm.identifierList)); (yyval.interm.intermNode) = 0; } -#line 5111 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 102: -#line 897 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { parseContext.nestedBlockCheck((yyvsp[-2].interm.type).loc); } -#line 5117 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5178 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 103: -#line 897 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 907 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { parseContext.nestedBlockCheck((yyvsp[-2].interm.type).loc); } +#line 5184 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 104: +#line 907 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { --parseContext.structNestingLevel; parseContext.blockName = (yyvsp[-4].lex).string; @@ -5129,54 +5194,54 @@ yyreduce: (yyval.interm).loc = (yyvsp[-5].interm.type).loc; (yyval.interm).typeList = (yyvsp[-1].interm.typeList); } -#line 5131 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5198 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 104: -#line 908 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 105: +#line 918 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.identifierList) = new TIdentifierList; (yyval.interm.identifierList)->push_back((yyvsp[0].lex).string); } -#line 5140 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5207 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 105: -#line 912 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 106: +#line 922 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.identifierList) = (yyvsp[-2].interm.identifierList); (yyval.interm.identifierList)->push_back((yyvsp[0].lex).string); } -#line 5149 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5216 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 106: -#line 919 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 107: +#line 929 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).function = (yyvsp[-1].interm.function); (yyval.interm).loc = (yyvsp[0].lex).loc; } -#line 5158 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 107: -#line 926 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.function) = (yyvsp[0].interm.function); - } -#line 5166 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5225 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 108: -#line 929 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 936 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.function) = (yyvsp[0].interm.function); } -#line 5174 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5233 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 109: -#line 936 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 939 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.function) = (yyvsp[0].interm.function); + } +#line 5241 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 110: +#line 946 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // Add the parameter (yyval.interm.function) = (yyvsp[-1].interm.function); @@ -5185,11 +5250,11 @@ yyreduce: else delete (yyvsp[0].interm).param.type; } -#line 5187 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5254 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 110: -#line 944 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 111: +#line 954 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // // Only first parameter of one-parameter functions can be void @@ -5207,11 +5272,11 @@ yyreduce: (yyvsp[-2].interm.function)->addParameter((yyvsp[0].interm).param); } } -#line 5209 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5276 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 111: -#line 964 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 112: +#line 974 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if ((yyvsp[-2].interm.type).qualifier.storage != EvqGlobal && (yyvsp[-2].interm.type).qualifier.storage != EvqTemporary) { parseContext.error((yyvsp[-1].lex).loc, "no qualifiers allowed for function return", @@ -5231,11 +5296,11 @@ yyreduce: function = new TFunction((yyvsp[-1].lex).string, type); (yyval.interm.function) = function; } -#line 5233 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5300 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 112: -#line 987 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 113: +#line 997 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if ((yyvsp[-1].interm.type).arraySizes) { parseContext.profileRequires((yyvsp[-1].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); @@ -5251,11 +5316,11 @@ yyreduce: (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).param = param; } -#line 5253 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5320 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 113: -#line 1002 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 114: +#line 1012 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if ((yyvsp[-2].interm.type).arraySizes) { parseContext.profileRequires((yyvsp[-2].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); @@ -5275,11 +5340,11 @@ yyreduce: (yyval.interm).loc = (yyvsp[-1].lex).loc; (yyval.interm).param = param; } -#line 5277 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5344 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 114: -#line 1027 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 115: +#line 1037 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[0].interm); if ((yyvsp[-1].interm.type).qualifier.precision != EpqNone) @@ -5291,11 +5356,11 @@ yyreduce: parseContext.paramCheckFix((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, *(yyval.interm).param.type); } -#line 5293 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5360 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 115: -#line 1038 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 116: +#line 1048 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[0].interm); @@ -5303,11 +5368,11 @@ yyreduce: parseContext.paramCheckFixStorage((yyvsp[0].interm).loc, EvqTemporary, *(yyval.interm).param.type); parseContext.precisionQualifierCheck((yyval.interm).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier()); } -#line 5305 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5372 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 116: -#line 1048 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 117: +#line 1058 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[0].interm); if ((yyvsp[-1].interm.type).qualifier.precision != EpqNone) @@ -5318,11 +5383,11 @@ yyreduce: parseContext.parameterTypeCheck((yyvsp[0].interm).loc, (yyvsp[-1].interm.type).qualifier.storage, *(yyval.interm).param.type); parseContext.paramCheckFix((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, *(yyval.interm).param.type); } -#line 5320 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5387 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 117: -#line 1058 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 118: +#line 1068 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[0].interm); @@ -5330,68 +5395,68 @@ yyreduce: parseContext.paramCheckFixStorage((yyvsp[0].interm).loc, EvqTemporary, *(yyval.interm).param.type); parseContext.precisionQualifierCheck((yyval.interm).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier()); } -#line 5332 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5399 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 118: -#line 1068 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 119: +#line 1078 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { TParameter param = { 0, new TType((yyvsp[0].interm.type)) }; (yyval.interm).param = param; if ((yyvsp[0].interm.type).arraySizes) parseContext.arraySizeRequiredCheck((yyvsp[0].interm.type).loc, *(yyvsp[0].interm.type).arraySizes); } -#line 5343 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 119: -#line 1077 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm) = (yyvsp[0].interm); - } -#line 5351 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5410 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 120: -#line 1080 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1087 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[0].interm); + } +#line 5418 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 121: +#line 1090 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[-2].interm); parseContext.declareVariable((yyvsp[0].lex).loc, *(yyvsp[0].lex).string, (yyvsp[-2].interm).type); } -#line 5360 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5427 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 121: -#line 1084 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 122: +#line 1094 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[-3].interm); parseContext.declareVariable((yyvsp[-1].lex).loc, *(yyvsp[-1].lex).string, (yyvsp[-3].interm).type, (yyvsp[0].interm).arraySizes); } -#line 5369 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5436 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 122: -#line 1088 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 123: +#line 1098 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).type = (yyvsp[-5].interm).type; TIntermNode* initNode = parseContext.declareVariable((yyvsp[-3].lex).loc, *(yyvsp[-3].lex).string, (yyvsp[-5].interm).type, (yyvsp[-2].interm).arraySizes, (yyvsp[0].interm.intermTypedNode)); (yyval.interm).intermNode = parseContext.intermediate.growAggregate((yyvsp[-5].interm).intermNode, initNode, (yyvsp[-1].lex).loc); } -#line 5379 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5446 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 123: -#line 1093 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 124: +#line 1103 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).type = (yyvsp[-4].interm).type; TIntermNode* initNode = parseContext.declareVariable((yyvsp[-2].lex).loc, *(yyvsp[-2].lex).string, (yyvsp[-4].interm).type, 0, (yyvsp[0].interm.intermTypedNode)); (yyval.interm).intermNode = parseContext.intermediate.growAggregate((yyvsp[-4].interm).intermNode, initNode, (yyvsp[-1].lex).loc); } -#line 5389 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5456 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 124: -#line 1101 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 125: +#line 1111 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).type = (yyvsp[0].interm.type); (yyval.interm).intermNode = 0; @@ -5399,51 +5464,51 @@ yyreduce: parseContext.declareTypeDefaults((yyval.interm).loc, (yyval.interm).type); } -#line 5401 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5468 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 125: -#line 1108 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 126: +#line 1118 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).type = (yyvsp[-1].interm.type); (yyval.interm).intermNode = 0; parseContext.declareVariable((yyvsp[0].lex).loc, *(yyvsp[0].lex).string, (yyvsp[-1].interm.type)); } -#line 5411 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5478 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 126: -#line 1113 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 127: +#line 1123 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).type = (yyvsp[-2].interm.type); (yyval.interm).intermNode = 0; parseContext.declareVariable((yyvsp[-1].lex).loc, *(yyvsp[-1].lex).string, (yyvsp[-2].interm.type), (yyvsp[0].interm).arraySizes); } -#line 5421 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5488 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 127: -#line 1118 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 128: +#line 1128 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).type = (yyvsp[-4].interm.type); TIntermNode* initNode = parseContext.declareVariable((yyvsp[-3].lex).loc, *(yyvsp[-3].lex).string, (yyvsp[-4].interm.type), (yyvsp[-2].interm).arraySizes, (yyvsp[0].interm.intermTypedNode)); (yyval.interm).intermNode = parseContext.intermediate.growAggregate(0, initNode, (yyvsp[-1].lex).loc); } -#line 5431 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5498 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 128: -#line 1123 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 129: +#line 1133 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).type = (yyvsp[-3].interm.type); TIntermNode* initNode = parseContext.declareVariable((yyvsp[-2].lex).loc, *(yyvsp[-2].lex).string, (yyvsp[-3].interm.type), 0, (yyvsp[0].interm.intermTypedNode)); (yyval.interm).intermNode = parseContext.intermediate.growAggregate(0, initNode, (yyvsp[-1].lex).loc); } -#line 5441 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5508 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 129: -#line 1132 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 130: +#line 1142 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type) = (yyvsp[0].interm.type); @@ -5454,11 +5519,11 @@ yyreduce: } parseContext.precisionQualifierCheck((yyval.interm.type).loc, (yyval.interm.type).basicType, (yyval.interm.type).qualifier); } -#line 5456 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5523 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 130: -#line 1142 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 131: +#line 1152 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalQualifierFixCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier); parseContext.globalQualifierTypeCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, (yyvsp[0].interm.type)); @@ -5483,22 +5548,22 @@ yyreduce: (parseContext.language == EShLangFragment && (yyval.interm.type).qualifier.storage == EvqVaryingIn))) (yyval.interm.type).qualifier.smooth = true; } -#line 5485 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5552 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 131: -#line 1169 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 132: +#line 1179 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "invariant"); parseContext.profileRequires((yyval.interm.type).loc, ENoProfile, 120, 0, "invariant"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.invariant = true; } -#line 5496 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5563 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 132: -#line 1178 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 133: +#line 1188 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "smooth"); parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "smooth"); @@ -5506,11 +5571,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.smooth = true; } -#line 5508 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5575 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 133: -#line 1185 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 134: +#line 1195 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "flat"); parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "flat"); @@ -5518,11 +5583,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.flat = true; } -#line 5520 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5587 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 134: -#line 1193 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 135: +#line 1203 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "noperspective"); parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 0, E_GL_NV_shader_noperspective_interpolation, "noperspective"); @@ -5530,11 +5595,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.nopersp = true; } -#line 5532 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5599 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 135: -#line 1200 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 136: +#line 1210 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "__explicitInterpAMD"); parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 450, E_GL_AMD_shader_explicit_vertex_parameter, "explicit interpolation"); @@ -5542,11 +5607,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.explicitInterp = true; } -#line 5544 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5611 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 136: -#line 1207 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 137: +#line 1217 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "pervertexNV"); parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric"); @@ -5555,11 +5620,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.pervertexNV = true; } -#line 5557 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5624 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 137: -#line 1215 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 138: +#line 1225 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // No need for profile version or extension check. Shader stage already checks both. parseContext.globalCheck((yyvsp[0].lex).loc, "perprimitiveNV"); @@ -5570,11 +5635,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.perPrimitiveNV = true; } -#line 5572 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5639 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 138: -#line 1225 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 139: +#line 1235 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // No need for profile version or extension check. Shader stage already checks both. parseContext.globalCheck((yyvsp[0].lex).loc, "perviewNV"); @@ -5582,11 +5647,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.perViewNV = true; } -#line 5584 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5651 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 139: -#line 1232 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 140: +#line 1242 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // No need for profile version or extension check. Shader stage already checks both. parseContext.globalCheck((yyvsp[0].lex).loc, "taskNV"); @@ -5594,84 +5659,84 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.perTaskNV = true; } -#line 5596 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 140: -#line 1243 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type) = (yyvsp[-1].interm.type); - } -#line 5604 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5663 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 141: -#line 1249 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1253 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.type) = (yyvsp[0].interm.type); + (yyval.interm.type) = (yyvsp[-1].interm.type); } -#line 5612 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5671 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 142: -#line 1252 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1259 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 5679 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 143: +#line 1262 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type) = (yyvsp[-2].interm.type); (yyval.interm.type).shaderQualifiers.merge((yyvsp[0].interm.type).shaderQualifiers); parseContext.mergeObjectLayoutQualifiers((yyval.interm.type).qualifier, (yyvsp[0].interm.type).qualifier, false); } -#line 5622 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5689 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 143: -#line 1259 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 144: +#line 1269 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.setLayoutQualifier((yyvsp[0].lex).loc, (yyval.interm.type), *(yyvsp[0].lex).string); } -#line 5631 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5698 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 144: -#line 1263 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 145: +#line 1273 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[-2].lex).loc); parseContext.setLayoutQualifier((yyvsp[-2].lex).loc, (yyval.interm.type), *(yyvsp[-2].lex).string, (yyvsp[0].interm.intermTypedNode)); } -#line 5640 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5707 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 145: -#line 1267 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 146: +#line 1277 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // because "shared" is both an identifier and a keyword (yyval.interm.type).init((yyvsp[0].lex).loc); TString strShared("shared"); parseContext.setLayoutQualifier((yyvsp[0].lex).loc, (yyval.interm.type), strShared); } -#line 5650 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5717 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 146: -#line 1276 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 147: +#line 1286 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.profileRequires((yyval.interm.type).loc, ECoreProfile | ECompatibilityProfile, 400, E_GL_ARB_gpu_shader5, "precise"); parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5, "precise"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.noContraction = true; } -#line 5661 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 147: -#line 1286 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type) = (yyvsp[0].interm.type); - } -#line 5669 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5728 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 148: -#line 1289 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1296 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 5736 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 149: +#line 1299 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type) = (yyvsp[-1].interm.type); if ((yyval.interm.type).basicType == EbtVoid) @@ -5680,112 +5745,112 @@ yyreduce: (yyval.interm.type).shaderQualifiers.merge((yyvsp[0].interm.type).shaderQualifiers); parseContext.mergeQualifiers((yyval.interm.type).loc, (yyval.interm.type).qualifier, (yyvsp[0].interm.type).qualifier, false); } -#line 5682 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 149: -#line 1300 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type) = (yyvsp[0].interm.type); - } -#line 5690 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5749 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 150: -#line 1303 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1310 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 5698 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5757 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 151: -#line 1306 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1313 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 5765 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 152: +#line 1316 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.checkPrecisionQualifier((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type).qualifier.precision); (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 5707 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 152: -#line 1310 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - // allow inheritance of storage qualifier from block declaration - (yyval.interm.type) = (yyvsp[0].interm.type); - } -#line 5716 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5774 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 153: -#line 1314 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1320 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // allow inheritance of storage qualifier from block declaration (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 5725 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5783 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 154: -#line 1319 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1324 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // allow inheritance of storage qualifier from block declaration (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 5734 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5792 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 155: -#line 1323 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1329 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { + // allow inheritance of storage qualifier from block declaration (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 5742 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5801 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 156: -#line 1330 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1333 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 5809 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 157: +#line 1340 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqConst; // will later turn into EvqConstReadOnly, if the initializer is not constant } -#line 5751 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5818 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 157: -#line 1334 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 158: +#line 1344 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "inout"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqInOut; } -#line 5761 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5828 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 158: -#line 1339 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 159: +#line 1349 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "in"); (yyval.interm.type).init((yyvsp[0].lex).loc); // whether this is a parameter "in" or a pipeline "in" will get sorted out a bit later (yyval.interm.type).qualifier.storage = EvqIn; } -#line 5772 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5839 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 159: -#line 1345 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 160: +#line 1355 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "out"); (yyval.interm.type).init((yyvsp[0].lex).loc); // whether this is a parameter "out" or a pipeline "out" will get sorted out a bit later (yyval.interm.type).qualifier.storage = EvqOut; } -#line 5783 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5850 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 160: -#line 1351 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 161: +#line 1361 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 120, 0, "centroid"); parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 300, 0, "centroid"); @@ -5793,21 +5858,21 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.centroid = true; } -#line 5795 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5862 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 161: -#line 1358 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 162: +#line 1368 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "uniform"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqUniform; } -#line 5805 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5872 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 162: -#line 1363 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 163: +#line 1373 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "shared"); parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared"); @@ -5816,21 +5881,21 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqShared; } -#line 5818 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5885 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 163: -#line 1371 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 164: +#line 1381 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "buffer"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqBuffer; } -#line 5828 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5895 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 164: -#line 1377 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 165: +#line 1387 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireStage((yyvsp[0].lex).loc, EShLangVertex, "attribute"); parseContext.checkDeprecated((yyvsp[0].lex).loc, ECoreProfile, 130, "attribute"); @@ -5843,11 +5908,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqVaryingIn; } -#line 5845 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5912 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 165: -#line 1389 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 166: +#line 1399 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.checkDeprecated((yyvsp[0].lex).loc, ENoProfile, 130, "varying"); parseContext.checkDeprecated((yyvsp[0].lex).loc, ECoreProfile, 130, "varying"); @@ -5862,250 +5927,324 @@ yyreduce: else (yyval.interm.type).qualifier.storage = EvqVaryingIn; } -#line 5864 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5931 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 166: -#line 1403 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 167: +#line 1413 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "patch"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangTessControlMask | EShLangTessEvaluationMask), "patch"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.patch = true; } -#line 5875 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5942 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 167: -#line 1409 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 168: +#line 1419 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "sample"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.sample = true; } -#line 5885 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 168: -#line 1414 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.globalCheck((yyvsp[0].lex).loc, "hitAttributeNV"); - parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangIntersectNVMask | EShLangClosestHitNVMask - | EShLangAnyHitNVMask), "hitAttributeNV"); - parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "hitAttributeNV"); - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.storage = EvqHitAttrNV; - } -#line 5898 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5952 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 169: -#line 1422 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1424 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.globalCheck((yyvsp[0].lex).loc, "rayPayloadNV"); - parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenNVMask | EShLangClosestHitNVMask | - EShLangAnyHitNVMask | EShLangMissNVMask), "rayPayloadNV"); - parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "rayPayloadNV"); + parseContext.globalCheck((yyvsp[0].lex).loc, "hitAttributeNV"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangIntersectMask | EShLangClosestHitMask + | EShLangAnyHitMask), "hitAttributeNV"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "hitAttributeNV"); (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.storage = EvqPayloadNV; + (yyval.interm.type).qualifier.storage = EvqHitAttr; } -#line 5911 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5965 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 170: -#line 1430 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1432 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.globalCheck((yyvsp[0].lex).loc, "rayPayloadInNV"); - parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangClosestHitNVMask | - EShLangAnyHitNVMask | EShLangMissNVMask), "rayPayloadInNV"); - parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "rayPayloadInNV"); + parseContext.globalCheck((yyvsp[0].lex).loc, "hitAttributeEXT"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangIntersectMask | EShLangClosestHitMask + | EShLangAnyHitMask), "hitAttributeEXT"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_EXT_ray_tracing, "hitAttributeNV"); (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.storage = EvqPayloadInNV; + (yyval.interm.type).qualifier.storage = EvqHitAttr; } -#line 5924 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5978 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 171: -#line 1438 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1440 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataNV"); - parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenNVMask | - EShLangClosestHitNVMask | EShLangMissNVMask | EShLangCallableNVMask), "callableDataNV"); - parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "callableDataNV"); + parseContext.globalCheck((yyvsp[0].lex).loc, "rayPayloadNV"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask | + EShLangAnyHitMask | EShLangMissMask), "rayPayloadNV"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "rayPayloadNV"); (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.storage = EvqCallableDataNV; + (yyval.interm.type).qualifier.storage = EvqPayload; } -#line 5937 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5991 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 172: -#line 1446 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1448 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataInNV"); - parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangCallableNVMask), "callableDataInNV"); - parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "callableDataInNV"); + parseContext.globalCheck((yyvsp[0].lex).loc, "rayPayloadEXT"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask | + EShLangAnyHitMask | EShLangMissMask), "rayPayloadEXT"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_EXT_ray_tracing, "rayPayloadEXT"); (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.storage = EvqCallableDataInNV; + (yyval.interm.type).qualifier.storage = EvqPayload; } -#line 5949 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6004 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 173: -#line 1453 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1456 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.globalCheck((yyvsp[0].lex).loc, "rayPayloadInNV"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangClosestHitMask | + EShLangAnyHitMask | EShLangMissMask), "rayPayloadInNV"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "rayPayloadInNV"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqPayloadIn; + } +#line 6017 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 174: +#line 1464 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.globalCheck((yyvsp[0].lex).loc, "rayPayloadInEXT"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangClosestHitMask | + EShLangAnyHitMask | EShLangMissMask), "rayPayloadInEXT"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_EXT_ray_tracing, "rayPayloadInEXT"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqPayloadIn; + } +#line 6030 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 175: +#line 1472 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataNV"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenMask | + EShLangClosestHitMask | EShLangMissMask | EShLangCallableMask), "callableDataNV"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "callableDataNV"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqCallableData; + } +#line 6043 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 176: +#line 1480 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataEXT"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenMask | + EShLangClosestHitMask | EShLangMissMask | EShLangCallableMask), "callableDataEXT"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_EXT_ray_tracing, "callableDataEXT"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqCallableData; + } +#line 6056 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 177: +#line 1488 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataInNV"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangCallableMask), "callableDataInNV"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "callableDataInNV"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqCallableDataIn; + } +#line 6068 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 178: +#line 1495 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataInEXT"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangCallableMask), "callableDataInEXT"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_EXT_ray_tracing, "callableDataInEXT"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqCallableDataIn; + } +#line 6080 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 179: +#line 1502 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.coherent = true; } -#line 5958 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6089 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 174: -#line 1457 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 180: +#line 1506 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "devicecoherent"); (yyval.interm.type).qualifier.devicecoherent = true; } -#line 5968 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6099 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 175: -#line 1462 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 181: +#line 1511 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "queuefamilycoherent"); (yyval.interm.type).qualifier.queuefamilycoherent = true; } -#line 5978 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6109 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 176: -#line 1467 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 182: +#line 1516 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "workgroupcoherent"); (yyval.interm.type).qualifier.workgroupcoherent = true; } -#line 5988 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6119 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 177: -#line 1472 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 183: +#line 1521 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "subgroupcoherent"); (yyval.interm.type).qualifier.subgroupcoherent = true; } -#line 5998 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6129 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 178: -#line 1477 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 184: +#line 1526 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "nonprivate"); (yyval.interm.type).qualifier.nonprivate = true; } -#line 6008 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6139 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 179: -#line 1482 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 185: +#line 1531 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc); + parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_EXT_ray_tracing, "shadercallcoherent"); + (yyval.interm.type).qualifier.shadercallcoherent = true; + } +#line 6149 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 186: +#line 1536 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.volatil = true; } -#line 6017 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6158 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 180: -#line 1486 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 187: +#line 1540 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.restrict = true; } -#line 6026 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6167 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 181: -#line 1490 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 188: +#line 1544 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.readonly = true; } -#line 6035 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6176 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 182: -#line 1494 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 189: +#line 1548 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.writeonly = true; } -#line 6044 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6185 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 183: -#line 1498 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 190: +#line 1552 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.spvRemoved((yyvsp[0].lex).loc, "subroutine"); parseContext.globalCheck((yyvsp[0].lex).loc, "subroutine"); parseContext.unimplemented((yyvsp[0].lex).loc, "subroutine"); (yyval.interm.type).init((yyvsp[0].lex).loc); } -#line 6055 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6196 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 184: -#line 1504 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 191: +#line 1558 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.spvRemoved((yyvsp[-3].lex).loc, "subroutine"); parseContext.globalCheck((yyvsp[-3].lex).loc, "subroutine"); parseContext.unimplemented((yyvsp[-3].lex).loc, "subroutine"); (yyval.interm.type).init((yyvsp[-3].lex).loc); } -#line 6066 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6207 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 185: -#line 1515 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 192: +#line 1569 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.nonUniform = true; } -#line 6075 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6216 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 186: -#line 1522 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 193: +#line 1576 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // TODO } -#line 6083 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6224 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 187: -#line 1525 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 194: +#line 1579 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // TODO: 4.0 semantics: subroutines // 1) make sure each identifier is a type declared earlier with SUBROUTINE // 2) save all of the identifiers for future comparison with the declared function } -#line 6093 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6234 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 188: -#line 1534 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 195: +#line 1588 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type) = (yyvsp[-1].interm.type); (yyval.interm.type).qualifier.precision = parseContext.getDefaultPrecision((yyval.interm.type)); (yyval.interm.type).typeParameters = (yyvsp[0].interm.typeParameters); } -#line 6103 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6244 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 189: -#line 1539 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 196: +#line 1593 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.arrayOfArrayVersionCheck((yyvsp[0].interm).loc, (yyvsp[0].interm).arraySizes); (yyval.interm.type) = (yyvsp[-2].interm.type); @@ -6113,21 +6252,21 @@ yyreduce: (yyval.interm.type).typeParameters = (yyvsp[-1].interm.typeParameters); (yyval.interm.type).arraySizes = (yyvsp[0].interm).arraySizes; } -#line 6115 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6256 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 190: -#line 1549 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 197: +#line 1603 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[-1].lex).loc; (yyval.interm).arraySizes = new TArraySizes; (yyval.interm).arraySizes->addInnerSize(); } -#line 6125 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6266 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 191: -#line 1554 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 198: +#line 1608 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[-2].lex).loc; (yyval.interm).arraySizes = new TArraySizes; @@ -6136,20 +6275,20 @@ yyreduce: parseContext.arraySizeCheck((yyvsp[-1].interm.intermTypedNode)->getLoc(), (yyvsp[-1].interm.intermTypedNode), size, "array size"); (yyval.interm).arraySizes->addInnerSize(size); } -#line 6138 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6279 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 192: -#line 1562 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 199: +#line 1616 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[-2].interm); (yyval.interm).arraySizes->addInnerSize(); } -#line 6147 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6288 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 193: -#line 1566 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 200: +#line 1620 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[-3].interm); @@ -6157,35 +6296,35 @@ yyreduce: parseContext.arraySizeCheck((yyvsp[-1].interm.intermTypedNode)->getLoc(), (yyvsp[-1].interm.intermTypedNode), size, "array size"); (yyval.interm).arraySizes->addInnerSize(size); } -#line 6159 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6300 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 194: -#line 1576 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 201: +#line 1630 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeParameters) = (yyvsp[0].interm.typeParameters); } -#line 6167 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6308 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 195: -#line 1579 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 202: +#line 1633 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeParameters) = 0; } -#line 6175 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6316 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 196: -#line 1585 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 203: +#line 1639 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeParameters) = (yyvsp[-1].interm.typeParameters); } -#line 6183 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6324 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 197: -#line 1591 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 204: +#line 1645 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeParameters) = new TArraySizes; @@ -6193,11 +6332,11 @@ yyreduce: parseContext.arraySizeCheck((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode), size, "type parameter"); (yyval.interm.typeParameters)->addInnerSize(size); } -#line 6195 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6336 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 198: -#line 1598 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 205: +#line 1652 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeParameters) = (yyvsp[-2].interm.typeParameters); @@ -6205,300 +6344,300 @@ yyreduce: parseContext.arraySizeCheck((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode), size, "type parameter"); (yyval.interm.typeParameters)->addInnerSize(size); } -#line 6207 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6348 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 199: -#line 1608 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 206: +#line 1662 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtVoid; } -#line 6216 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6357 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 200: -#line 1612 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 207: +#line 1666 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; } -#line 6225 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6366 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 201: -#line 1616 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 208: +#line 1670 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; } -#line 6234 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6375 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 202: -#line 1620 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 209: +#line 1674 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; } -#line 6244 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 203: -#line 1625 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtBool; - } -#line 6253 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 204: -#line 1629 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setVector(2); - } -#line 6263 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 205: -#line 1634 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setVector(3); - } -#line 6273 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 206: -#line 1639 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setVector(4); - } -#line 6283 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 207: -#line 1644 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtBool; - (yyval.interm.type).setVector(2); - } -#line 6293 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 208: -#line 1649 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtBool; - (yyval.interm.type).setVector(3); - } -#line 6303 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 209: -#line 1654 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtBool; - (yyval.interm.type).setVector(4); - } -#line 6313 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6385 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 210: -#line 1659 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1679 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt; - (yyval.interm.type).setVector(2); + (yyval.interm.type).basicType = EbtBool; } -#line 6323 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6394 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 211: -#line 1664 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1683 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setVector(2); + } +#line 6404 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 212: +#line 1688 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setVector(3); + } +#line 6414 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 213: +#line 1693 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setVector(4); + } +#line 6424 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 214: +#line 1698 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtBool; + (yyval.interm.type).setVector(2); + } +#line 6434 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 215: +#line 1703 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtBool; + (yyval.interm.type).setVector(3); + } +#line 6444 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 216: +#line 1708 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtBool; + (yyval.interm.type).setVector(4); + } +#line 6454 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 217: +#line 1713 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; + (yyval.interm.type).setVector(2); + } +#line 6464 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 218: +#line 1718 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; (yyval.interm.type).setVector(3); } -#line 6333 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6474 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 212: -#line 1669 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 219: +#line 1723 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; (yyval.interm.type).setVector(4); } -#line 6343 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6484 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 213: -#line 1674 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 220: +#line 1728 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; (yyval.interm.type).setVector(2); } -#line 6354 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6495 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 214: -#line 1680 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 221: +#line 1734 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; (yyval.interm.type).setVector(3); } -#line 6365 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6506 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 215: -#line 1686 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 222: +#line 1740 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; (yyval.interm.type).setVector(4); } -#line 6376 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6517 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 216: -#line 1692 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 223: +#line 1746 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 2); } -#line 6386 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6527 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 217: -#line 1697 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 224: +#line 1751 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 3); } -#line 6396 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6537 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 218: -#line 1702 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 225: +#line 1756 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 4); } -#line 6406 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6547 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 219: -#line 1707 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 226: +#line 1761 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 2); } -#line 6416 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6557 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 220: -#line 1712 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 227: +#line 1766 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 3); } -#line 6426 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6567 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 221: -#line 1717 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 228: +#line 1771 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 4); } -#line 6436 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6577 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 222: -#line 1722 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 229: +#line 1776 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 2); } -#line 6446 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6587 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 223: -#line 1727 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 230: +#line 1781 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 3); } -#line 6456 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6597 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 224: -#line 1732 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 231: +#line 1786 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 4); } -#line 6466 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6607 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 225: -#line 1737 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 232: +#line 1791 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 2); } -#line 6476 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6617 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 226: -#line 1742 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 233: +#line 1796 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 3); } -#line 6486 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6627 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 227: -#line 1747 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 234: +#line 1801 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 4); } -#line 6496 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6637 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 228: -#line 1753 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 235: +#line 1807 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -6506,2658 +6645,2676 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; } -#line 6506 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6649 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 229: -#line 1758 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 236: +#line 1814 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "float16_t", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; } -#line 6516 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6659 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 230: -#line 1763 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 237: +#line 1819 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; } -#line 6526 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6669 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 231: -#line 1768 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 238: +#line 1824 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; } -#line 6536 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6679 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 232: -#line 1773 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 239: +#line 1829 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt8; } -#line 6546 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6689 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 233: -#line 1778 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 240: +#line 1834 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint8; } -#line 6556 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6699 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 234: -#line 1783 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 241: +#line 1839 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt16; } -#line 6566 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6709 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 235: -#line 1788 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 242: +#line 1844 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint16; } -#line 6576 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6719 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 236: -#line 1793 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 243: +#line 1849 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; } -#line 6586 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6729 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 237: -#line 1798 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 244: +#line 1854 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; } -#line 6596 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6739 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 238: -#line 1803 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 245: +#line 1859 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt64; } -#line 6606 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6749 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 239: -#line 1808 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 246: +#line 1864 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint64; } -#line 6616 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 240: -#line 1813 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double vector"); - if (! parseContext.symbolTable.atBuiltInLevel()) - parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtDouble; - (yyval.interm.type).setVector(2); - } -#line 6627 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 241: -#line 1819 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double vector"); - if (! parseContext.symbolTable.atBuiltInLevel()) - parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtDouble; - (yyval.interm.type).setVector(3); - } -#line 6638 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 242: -#line 1825 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double vector"); - if (! parseContext.symbolTable.atBuiltInLevel()) - parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtDouble; - (yyval.interm.type).setVector(4); - } -#line 6649 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 243: -#line 1831 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setVector(2); - } -#line 6660 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 244: -#line 1837 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setVector(3); - } -#line 6671 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 245: -#line 1843 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setVector(4); - } -#line 6682 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 246: -#line 1849 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setVector(2); - } -#line 6693 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 247: -#line 1855 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setVector(3); - } -#line 6704 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 248: -#line 1861 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setVector(4); - } -#line 6715 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 249: -#line 1867 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtDouble; - (yyval.interm.type).setVector(2); - } -#line 6726 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 250: -#line 1873 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtDouble; - (yyval.interm.type).setVector(3); - } -#line 6737 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 251: -#line 1879 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtDouble; - (yyval.interm.type).setVector(4); - } -#line 6748 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 252: -#line 1885 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt8; - (yyval.interm.type).setVector(2); - } #line 6759 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 253: -#line 1891 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 247: +#line 1869 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double vector"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt8; + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setVector(2); + } +#line 6772 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 248: +#line 1877 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double vector"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setVector(3); } -#line 6770 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6785 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 249: +#line 1885 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double vector"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setVector(4); + } +#line 6798 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 250: +#line 1893 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setVector(2); + } +#line 6809 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 251: +#line 1899 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setVector(3); + } +#line 6820 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 252: +#line 1905 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setVector(4); + } +#line 6831 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 253: +#line 1911 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setVector(2); + } +#line 6842 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 254: -#line 1897 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1917 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setVector(3); + } +#line 6853 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 255: +#line 1923 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setVector(4); + } +#line 6864 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 256: +#line 1929 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setVector(2); + } +#line 6875 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 257: +#line 1935 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setVector(3); + } +#line 6886 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 258: +#line 1941 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setVector(4); + } +#line 6897 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 259: +#line 1947 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt8; + (yyval.interm.type).setVector(2); + } +#line 6908 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 260: +#line 1953 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt8; + (yyval.interm.type).setVector(3); + } +#line 6919 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 261: +#line 1959 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt8; (yyval.interm.type).setVector(4); } -#line 6781 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 255: -#line 1903 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt16; - (yyval.interm.type).setVector(2); - } -#line 6792 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 256: -#line 1909 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt16; - (yyval.interm.type).setVector(3); - } -#line 6803 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 257: -#line 1915 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt16; - (yyval.interm.type).setVector(4); - } -#line 6814 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 258: -#line 1921 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt; - (yyval.interm.type).setVector(2); - } -#line 6825 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 259: -#line 1927 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt; - (yyval.interm.type).setVector(3); - } -#line 6836 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 260: -#line 1933 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt; - (yyval.interm.type).setVector(4); - } -#line 6847 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 261: -#line 1939 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt64; - (yyval.interm.type).setVector(2); - } -#line 6858 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6930 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 262: -#line 1945 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1965 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt64; - (yyval.interm.type).setVector(3); + (yyval.interm.type).basicType = EbtInt16; + (yyval.interm.type).setVector(2); } -#line 6869 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6941 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 263: -#line 1951 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1971 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt16; + (yyval.interm.type).setVector(3); + } +#line 6952 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 264: +#line 1977 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt16; + (yyval.interm.type).setVector(4); + } +#line 6963 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 265: +#line 1983 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; + (yyval.interm.type).setVector(2); + } +#line 6974 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 266: +#line 1989 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; + (yyval.interm.type).setVector(3); + } +#line 6985 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 267: +#line 1995 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; + (yyval.interm.type).setVector(4); + } +#line 6996 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 268: +#line 2001 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt64; + (yyval.interm.type).setVector(2); + } +#line 7007 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 269: +#line 2007 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt64; + (yyval.interm.type).setVector(3); + } +#line 7018 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 270: +#line 2013 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt64; (yyval.interm.type).setVector(4); } -#line 6880 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 264: -#line 1957 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtUint8; - (yyval.interm.type).setVector(2); - } -#line 6891 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 265: -#line 1963 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtUint8; - (yyval.interm.type).setVector(3); - } -#line 6902 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 266: -#line 1969 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtUint8; - (yyval.interm.type).setVector(4); - } -#line 6913 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 267: -#line 1975 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtUint16; - (yyval.interm.type).setVector(2); - } -#line 6924 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 268: -#line 1981 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtUint16; - (yyval.interm.type).setVector(3); - } -#line 6935 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 269: -#line 1987 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtUint16; - (yyval.interm.type).setVector(4); - } -#line 6946 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 270: -#line 1993 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtUint; - (yyval.interm.type).setVector(2); - } -#line 6957 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7029 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 271: -#line 1999 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2019 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint8; + (yyval.interm.type).setVector(2); + } +#line 7040 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 272: +#line 2025 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint8; + (yyval.interm.type).setVector(3); + } +#line 7051 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 273: +#line 2031 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint8; + (yyval.interm.type).setVector(4); + } +#line 7062 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 274: +#line 2037 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint16; + (yyval.interm.type).setVector(2); + } +#line 7073 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 275: +#line 2043 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint16; + (yyval.interm.type).setVector(3); + } +#line 7084 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 276: +#line 2049 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint16; + (yyval.interm.type).setVector(4); + } +#line 7095 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 277: +#line 2055 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint; + (yyval.interm.type).setVector(2); + } +#line 7106 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 278: +#line 2061 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; (yyval.interm.type).setVector(3); } -#line 6968 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7117 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 272: -#line 2005 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 279: +#line 2067 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; (yyval.interm.type).setVector(4); } -#line 6979 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7128 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 273: -#line 2011 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 280: +#line 2073 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint64; (yyval.interm.type).setVector(2); } -#line 6990 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7139 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 274: -#line 2017 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 281: +#line 2079 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint64; (yyval.interm.type).setVector(3); } -#line 7001 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7150 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 275: -#line 2023 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 282: +#line 2085 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint64; (yyval.interm.type).setVector(4); } -#line 7012 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 276: -#line 2029 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); - if (! parseContext.symbolTable.atBuiltInLevel()) - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtDouble; - (yyval.interm.type).setMatrix(2, 2); - } -#line 7023 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 277: -#line 2035 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); - if (! parseContext.symbolTable.atBuiltInLevel()) - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtDouble; - (yyval.interm.type).setMatrix(3, 3); - } -#line 7034 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 278: -#line 2041 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); - if (! parseContext.symbolTable.atBuiltInLevel()) - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtDouble; - (yyval.interm.type).setMatrix(4, 4); - } -#line 7045 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 279: -#line 2047 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); - if (! parseContext.symbolTable.atBuiltInLevel()) - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtDouble; - (yyval.interm.type).setMatrix(2, 2); - } -#line 7056 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 280: -#line 2053 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); - if (! parseContext.symbolTable.atBuiltInLevel()) - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtDouble; - (yyval.interm.type).setMatrix(2, 3); - } -#line 7067 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 281: -#line 2059 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); - if (! parseContext.symbolTable.atBuiltInLevel()) - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtDouble; - (yyval.interm.type).setMatrix(2, 4); - } -#line 7078 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 282: -#line 2065 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); - if (! parseContext.symbolTable.atBuiltInLevel()) - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtDouble; - (yyval.interm.type).setMatrix(3, 2); - } -#line 7089 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7161 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 283: -#line 2071 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2091 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; - (yyval.interm.type).setMatrix(3, 3); + (yyval.interm.type).setMatrix(2, 2); } -#line 7100 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7174 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 284: -#line 2077 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2099 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; - (yyval.interm.type).setMatrix(3, 4); + (yyval.interm.type).setMatrix(3, 3); } -#line 7111 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7187 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 285: -#line 2083 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2107 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; - (yyval.interm.type).setMatrix(4, 2); + (yyval.interm.type).setMatrix(4, 4); } -#line 7122 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7200 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 286: -#line 2089 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2115 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; - (yyval.interm.type).setMatrix(4, 3); + (yyval.interm.type).setMatrix(2, 2); } -#line 7133 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7213 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 287: -#line 2095 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2123 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; - (yyval.interm.type).setMatrix(4, 4); + (yyval.interm.type).setMatrix(2, 3); } -#line 7144 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7226 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 288: -#line 2101 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2131 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setMatrix(2, 2); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(2, 4); } -#line 7155 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7239 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 289: -#line 2107 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2139 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setMatrix(3, 3); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(3, 2); } -#line 7166 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7252 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 290: -#line 2113 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2147 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setMatrix(4, 4); - } -#line 7177 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 291: -#line 2119 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setMatrix(2, 2); - } -#line 7188 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 292: -#line 2125 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setMatrix(2, 3); - } -#line 7199 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 293: -#line 2131 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setMatrix(2, 4); - } -#line 7210 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 294: -#line 2137 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setMatrix(3, 2); - } -#line 7221 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 295: -#line 2143 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 3); } -#line 7232 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 296: -#line 2149 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setMatrix(3, 4); - } -#line 7243 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 297: -#line 2155 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setMatrix(4, 2); - } -#line 7254 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 298: -#line 2161 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setMatrix(4, 3); - } #line 7265 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 299: -#line 2167 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 291: +#line 2155 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(3, 4); + } +#line 7278 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 292: +#line 2163 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(4, 2); + } +#line 7291 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 293: +#line 2171 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(4, 3); + } +#line 7304 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 294: +#line 2179 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(4, 4); + } +#line 7317 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 295: +#line 2187 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(2, 2); + } +#line 7328 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 296: +#line 2193 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(3, 3); + } +#line 7339 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 297: +#line 2199 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(4, 4); } -#line 7276 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7350 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 298: +#line 2205 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(2, 2); + } +#line 7361 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 299: +#line 2211 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(2, 3); + } +#line 7372 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 300: -#line 2173 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2217 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setMatrix(2, 2); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(2, 4); } -#line 7287 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7383 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 301: -#line 2179 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2223 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setMatrix(3, 3); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(3, 2); } -#line 7298 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7394 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 302: -#line 2185 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2229 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setMatrix(4, 4); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(3, 3); } -#line 7309 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7405 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 303: -#line 2191 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2235 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setMatrix(2, 2); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(3, 4); } -#line 7320 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7416 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 304: -#line 2197 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2241 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setMatrix(2, 3); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(4, 2); } -#line 7331 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7427 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 305: -#line 2203 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2247 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(4, 3); + } +#line 7438 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 306: +#line 2253 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(4, 4); + } +#line 7449 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 307: +#line 2259 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(2, 2); + } +#line 7460 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 308: +#line 2265 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(3, 3); + } +#line 7471 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 309: +#line 2271 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(4, 4); + } +#line 7482 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 310: +#line 2277 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(2, 2); + } +#line 7493 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 311: +#line 2283 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(2, 3); + } +#line 7504 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 312: +#line 2289 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 4); } -#line 7342 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7515 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 306: -#line 2209 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 313: +#line 2295 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 2); } -#line 7353 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7526 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 307: -#line 2215 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 314: +#line 2301 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 3); } -#line 7364 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7537 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 308: -#line 2221 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 315: +#line 2307 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 4); } -#line 7375 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7548 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 309: -#line 2227 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 316: +#line 2313 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 2); } -#line 7386 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7559 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 310: -#line 2233 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 317: +#line 2319 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 3); } -#line 7397 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7570 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 311: -#line 2239 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 318: +#line 2325 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 4); } -#line 7408 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7581 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 312: -#line 2245 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 319: +#line 2331 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 2); } -#line 7419 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7592 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 313: -#line 2251 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 320: +#line 2337 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 3); } -#line 7430 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7603 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 314: -#line 2257 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 321: +#line 2343 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 4); } -#line 7441 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7614 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 315: -#line 2263 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 322: +#line 2349 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 2); } -#line 7452 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7625 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 316: -#line 2269 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 323: +#line 2355 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 3); } -#line 7463 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7636 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 317: -#line 2275 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 324: +#line 2361 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 4); } -#line 7474 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7647 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 318: -#line 2281 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 325: +#line 2367 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 2); } -#line 7485 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7658 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 319: -#line 2287 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 326: +#line 2373 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 3); } -#line 7496 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7669 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 320: -#line 2293 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 327: +#line 2379 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 4); } -#line 7507 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7680 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 321: -#line 2299 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 328: +#line 2385 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 2); } -#line 7518 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7691 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 322: -#line 2305 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 329: +#line 2391 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 3); } -#line 7529 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7702 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 323: -#line 2311 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 330: +#line 2397 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 4); } -#line 7540 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7713 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 324: -#line 2317 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 331: +#line 2403 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtAccStructNV; + (yyval.interm.type).basicType = EbtAccStruct; } -#line 7549 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7722 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 325: -#line 2321 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 332: +#line 2407 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtAccStruct; + } +#line 7731 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 333: +#line 2411 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtRayQuery; + } +#line 7740 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 334: +#line 2415 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.vulkanRemoved((yyvsp[0].lex).loc, "atomic counter types"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtAtomicUint; } -#line 7559 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7750 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 326: -#line 2326 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 335: +#line 2420 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd1D); } -#line 7569 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7760 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 327: -#line 2332 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 336: +#line 2426 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D); } -#line 7579 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7770 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 328: -#line 2337 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 337: +#line 2431 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd3D); } -#line 7589 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7780 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 329: -#line 2342 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 338: +#line 2436 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdCube); } -#line 7599 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7790 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 330: -#line 2347 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 339: +#line 2441 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D, false, true); } -#line 7609 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7800 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 331: -#line 2352 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 340: +#line 2446 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdCube, false, true); } -#line 7619 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7810 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 332: -#line 2357 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 341: +#line 2451 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D, true); } -#line 7629 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7820 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 333: -#line 2362 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 342: +#line 2456 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D, true, true); } -#line 7639 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7830 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 334: -#line 2368 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 343: +#line 2462 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd1D, false, true); } -#line 7649 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7840 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 335: -#line 2373 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 344: +#line 2467 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd1D, true); } -#line 7659 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7850 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 336: -#line 2378 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 345: +#line 2472 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd1D, true, true); } -#line 7669 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7860 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 337: -#line 2383 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 346: +#line 2477 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdCube, true); } -#line 7679 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7870 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 338: -#line 2388 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 347: +#line 2482 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdCube, true, true); } -#line 7689 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7880 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 339: -#line 2393 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 348: +#line 2487 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd1D); } -#line 7700 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7891 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 340: -#line 2399 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 349: +#line 2493 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd2D); } -#line 7711 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7902 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 341: -#line 2405 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 350: +#line 2499 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd3D); } -#line 7722 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7913 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 342: -#line 2411 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 351: +#line 2505 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdCube); } -#line 7733 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7924 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 343: -#line 2417 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 352: +#line 2511 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd1D, false, true); } -#line 7744 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7935 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 344: -#line 2423 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 353: +#line 2517 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, false, true); } -#line 7755 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7946 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 345: -#line 2429 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 354: +#line 2523 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdCube, false, true); } -#line 7766 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7957 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 346: -#line 2435 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 355: +#line 2529 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd1D, true); } -#line 7777 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7968 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 347: -#line 2441 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 356: +#line 2535 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, true); } -#line 7788 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7979 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 348: -#line 2447 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 357: +#line 2541 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd1D, true, true); } -#line 7799 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7990 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 349: -#line 2453 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 358: +#line 2547 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, true, true); } -#line 7810 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8001 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 350: -#line 2459 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 359: +#line 2553 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdCube, true); } -#line 7821 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8012 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 351: -#line 2465 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 360: +#line 2559 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdCube, true, true); } -#line 7832 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8023 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 352: -#line 2471 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 361: +#line 2565 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd1D); } -#line 7842 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8033 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 353: -#line 2477 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 362: +#line 2571 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd2D); } -#line 7852 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8043 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 354: -#line 2482 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 363: +#line 2576 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd3D); } -#line 7862 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8053 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 355: -#line 2487 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 364: +#line 2581 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, EsdCube); } -#line 7872 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8063 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 356: -#line 2492 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 365: +#line 2586 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd2D, true); } -#line 7882 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8073 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 357: -#line 2497 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 366: +#line 2591 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd2D); } -#line 7892 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8083 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 358: -#line 2502 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 367: +#line 2596 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd3D); } -#line 7902 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8093 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 359: -#line 2507 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 368: +#line 2601 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, EsdCube); } -#line 7912 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8103 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 360: -#line 2513 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 369: +#line 2607 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd1D, true); } -#line 7922 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8113 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 361: -#line 2518 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 370: +#line 2612 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, EsdCube, true); } -#line 7932 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8123 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 362: -#line 2523 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 371: +#line 2617 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd1D); } -#line 7942 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8133 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 363: -#line 2528 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 372: +#line 2622 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd1D, true); } -#line 7952 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8143 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 364: -#line 2533 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 373: +#line 2627 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, EsdCube, true); } -#line 7962 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8153 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 365: -#line 2538 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 374: +#line 2632 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, EsdCube, true); } -#line 7972 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8163 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 366: -#line 2543 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 375: +#line 2637 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, EsdCube, true); } -#line 7982 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8173 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 367: -#line 2548 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 376: +#line 2642 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, EsdCube, true); } -#line 7992 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8183 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 368: -#line 2554 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 377: +#line 2648 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd2D, true); } -#line 8002 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8193 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 369: -#line 2559 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 378: +#line 2653 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D); } -#line 8012 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8203 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 370: -#line 2564 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 379: +#line 2658 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd3D); } -#line 8022 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8213 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 371: -#line 2569 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 380: +#line 2663 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D, true); } -#line 8032 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8223 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 372: -#line 2574 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 381: +#line 2668 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, EsdCube); } -#line 8042 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8233 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 373: -#line 2579 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 382: +#line 2673 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D); } -#line 8052 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8243 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 374: -#line 2584 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 383: +#line 2678 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd3D); } -#line 8062 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8253 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 375: -#line 2589 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 384: +#line 2683 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, EsdCube); } -#line 8072 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8263 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 376: -#line 2594 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 385: +#line 2688 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D, true); } -#line 8082 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8273 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 377: -#line 2599 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 386: +#line 2693 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D); } -#line 8092 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8283 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 378: -#line 2604 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 387: +#line 2698 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd3D); } -#line 8102 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8293 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 379: -#line 2609 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 388: +#line 2703 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, EsdCube); } -#line 8112 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8303 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 380: -#line 2614 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 389: +#line 2708 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D, true); } -#line 8122 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8313 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 381: -#line 2619 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 390: +#line 2713 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setPureSampler(false); } -#line 8132 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8323 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 382: -#line 2624 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 391: +#line 2718 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setPureSampler(true); } -#line 8142 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8333 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 383: -#line 2630 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 392: +#line 2724 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdRect); } -#line 8152 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8343 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 384: -#line 2635 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 393: +#line 2729 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdRect, false, true); } -#line 8162 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8353 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 385: -#line 2640 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 394: +#line 2734 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdRect); } -#line 8173 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8364 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 386: -#line 2646 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 395: +#line 2740 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdRect, false, true); } -#line 8184 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8375 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 387: -#line 2652 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 396: +#line 2746 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, EsdRect); } -#line 8194 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8385 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 388: -#line 2657 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 397: +#line 2751 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, EsdRect); } -#line 8204 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8395 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 389: -#line 2662 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 398: +#line 2756 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdBuffer); } -#line 8214 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8405 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 390: -#line 2667 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 399: +#line 2761 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdBuffer); } -#line 8225 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8416 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 391: -#line 2673 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 400: +#line 2767 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, EsdBuffer); } -#line 8235 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8426 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 392: -#line 2678 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 401: +#line 2772 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, EsdBuffer); } -#line 8245 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8436 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 393: -#line 2683 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 402: +#line 2777 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D, false, false, true); } -#line 8255 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8446 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 394: -#line 2688 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 403: +#line 2782 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, false, false, true); } -#line 8266 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8457 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 395: -#line 2694 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 404: +#line 2788 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd2D, false, false, true); } -#line 8276 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8467 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 396: -#line 2699 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 405: +#line 2793 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd2D, false, false, true); } -#line 8286 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8477 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 397: -#line 2704 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 406: +#line 2798 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D, true, false, true); } -#line 8296 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8487 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 398: -#line 2709 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 407: +#line 2803 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, true, false, true); } -#line 8307 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8498 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 399: -#line 2715 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 408: +#line 2809 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd2D, true, false, true); } -#line 8317 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8508 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 400: -#line 2720 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 409: +#line 2814 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd2D, true, false, true); } -#line 8327 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8518 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 401: -#line 2725 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 410: +#line 2819 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd1D); } -#line 8337 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8528 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 402: -#line 2730 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 411: +#line 2824 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd1D); } -#line 8348 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8539 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 403: -#line 2736 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 412: +#line 2830 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd2D); } -#line 8359 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8550 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 404: -#line 2742 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 413: +#line 2836 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd3D); } -#line 8370 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8561 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 405: -#line 2748 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 414: +#line 2842 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, EsdCube); } -#line 8381 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8572 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 406: -#line 2754 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 415: +#line 2848 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd1D, true); } -#line 8391 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8582 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 407: -#line 2759 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 416: +#line 2853 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd1D, true); } -#line 8402 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8593 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 408: -#line 2765 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 417: +#line 2859 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd2D, true); } -#line 8413 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8604 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 409: -#line 2771 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 418: +#line 2865 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, EsdCube, true); } -#line 8424 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8615 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 410: -#line 2777 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 419: +#line 2871 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd1D); } -#line 8434 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8625 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 411: -#line 2782 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 420: +#line 2876 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd1D, true); } -#line 8444 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8635 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 412: -#line 2787 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 421: +#line 2881 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd1D); } -#line 8454 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8645 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 413: -#line 2792 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 422: +#line 2886 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd1D, true); } -#line 8464 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8655 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 414: -#line 2797 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 423: +#line 2891 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, EsdRect); } -#line 8474 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8665 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 415: -#line 2802 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 424: +#line 2896 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, EsdRect); } -#line 8485 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8676 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 416: -#line 2808 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 425: +#line 2902 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, EsdRect); } -#line 8495 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8686 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 417: -#line 2813 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 426: +#line 2907 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, EsdRect); } -#line 8505 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8696 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 418: -#line 2818 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 427: +#line 2912 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, EsdBuffer); } -#line 8515 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8706 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 419: -#line 2823 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 428: +#line 2917 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, EsdBuffer); } -#line 8526 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8717 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 420: -#line 2829 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 429: +#line 2923 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, EsdBuffer); } -#line 8536 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8727 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 421: -#line 2834 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 430: +#line 2928 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, EsdBuffer); } -#line 8546 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8737 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 422: -#line 2839 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 431: +#line 2933 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D, false, false, true); } -#line 8556 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8747 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 423: -#line 2844 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 432: +#line 2938 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd2D, false, false, true); } -#line 8567 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8758 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 424: -#line 2850 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 433: +#line 2944 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D, false, false, true); } -#line 8577 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8768 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 425: -#line 2855 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 434: +#line 2949 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D, false, false, true); } -#line 8587 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8778 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 426: -#line 2860 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 435: +#line 2954 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D, true, false, true); } -#line 8597 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8788 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 427: -#line 2865 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 436: +#line 2959 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd2D, true, false, true); } -#line 8608 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8799 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 428: -#line 2871 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 437: +#line 2965 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D, true, false, true); } -#line 8618 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8809 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 429: -#line 2876 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 438: +#line 2970 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D, true, false, true); } -#line 8628 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8819 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 430: -#line 2881 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 439: +#line 2975 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd1D); } -#line 8638 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8829 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 431: -#line 2886 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 440: +#line 2980 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd1D); } -#line 8649 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8840 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 432: -#line 2892 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 441: +#line 2986 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd1D); } -#line 8659 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8850 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 433: -#line 2897 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 442: +#line 2991 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd1D); } -#line 8669 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8860 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 434: -#line 2902 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 443: +#line 2996 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D); } -#line 8679 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8870 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 435: -#line 2907 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 444: +#line 3001 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd2D); } -#line 8690 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8881 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 436: -#line 2913 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 445: +#line 3007 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd2D); } -#line 8700 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8891 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 437: -#line 2918 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 446: +#line 3012 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd2D); } -#line 8710 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8901 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 438: -#line 2923 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 447: +#line 3017 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd3D); } -#line 8720 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8911 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 439: -#line 2928 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 448: +#line 3022 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd3D); } -#line 8731 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8922 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 440: -#line 2934 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 449: +#line 3028 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd3D); } -#line 8741 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8932 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 441: -#line 2939 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 450: +#line 3033 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd3D); } -#line 8751 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8942 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 442: -#line 2944 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 451: +#line 3038 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, EsdRect); } -#line 8761 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8952 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 443: -#line 2949 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 452: +#line 3043 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, EsdRect); } -#line 8772 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8963 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 444: -#line 2955 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 453: +#line 3049 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, EsdRect); } -#line 8782 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8973 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 445: -#line 2960 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 454: +#line 3054 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, EsdRect); } -#line 8792 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8983 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 446: -#line 2965 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 455: +#line 3059 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, EsdCube); } -#line 8802 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8993 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 447: -#line 2970 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 456: +#line 3064 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, EsdCube); } -#line 8813 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9004 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 448: -#line 2976 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 457: +#line 3070 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, EsdCube); } -#line 8823 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9014 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 449: -#line 2981 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 458: +#line 3075 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, EsdCube); } -#line 8833 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9024 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 450: -#line 2986 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 459: +#line 3080 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, EsdBuffer); } -#line 8843 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9034 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 451: -#line 2991 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 460: +#line 3085 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, EsdBuffer); } -#line 8854 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9045 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 452: -#line 2997 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 461: +#line 3091 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, EsdBuffer); } -#line 8864 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9055 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 453: -#line 3002 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 462: +#line 3096 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, EsdBuffer); } -#line 8874 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9065 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 454: -#line 3007 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 463: +#line 3101 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd1D, true); } -#line 8884 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9075 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 455: -#line 3012 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 464: +#line 3106 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd1D, true); } -#line 8895 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9086 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 456: -#line 3018 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 465: +#line 3112 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd1D, true); } -#line 8905 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9096 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 457: -#line 3023 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 466: +#line 3117 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd1D, true); } -#line 8915 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9106 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 458: -#line 3028 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 467: +#line 3122 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D, true); } -#line 8925 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9116 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 459: -#line 3033 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 468: +#line 3127 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd2D, true); } -#line 8936 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9127 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 460: -#line 3039 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 469: +#line 3133 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd2D, true); } -#line 8946 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9137 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 461: -#line 3044 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 470: +#line 3138 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd2D, true); } -#line 8956 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9147 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 462: -#line 3049 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 471: +#line 3143 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, EsdCube, true); } -#line 8966 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9157 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 463: -#line 3054 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 472: +#line 3148 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, EsdCube, true); } -#line 8977 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9168 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 464: -#line 3060 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 473: +#line 3154 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, EsdCube, true); } -#line 8987 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9178 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 465: -#line 3065 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 474: +#line 3159 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, EsdCube, true); } -#line 8997 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9188 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 466: -#line 3070 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 475: +#line 3164 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D, false, false, true); } -#line 9007 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9198 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 467: -#line 3075 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 476: +#line 3169 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd2D, false, false, true); } -#line 9018 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9209 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 468: -#line 3081 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 477: +#line 3175 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd2D, false, false, true); } -#line 9028 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9219 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 469: -#line 3086 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 478: +#line 3180 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd2D, false, false, true); } -#line 9038 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9229 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 470: -#line 3091 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 479: +#line 3185 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D, true, false, true); } -#line 9048 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9239 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 471: -#line 3096 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 480: +#line 3190 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd2D, true, false, true); } -#line 9059 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9250 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 472: -#line 3102 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 481: +#line 3196 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd2D, true, false, true); } -#line 9069 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9260 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 473: -#line 3107 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 482: +#line 3201 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd2D, true, false, true); } -#line 9079 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9270 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 474: -#line 3112 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 483: +#line 3206 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // GL_OES_EGL_image_external (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D); (yyval.interm.type).sampler.external = true; } -#line 9090 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9281 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 475: -#line 3118 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 484: +#line 3212 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // GL_EXT_YUV_target (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D); (yyval.interm.type).sampler.yuv = true; } -#line 9101 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9292 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 476: -#line 3124 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 485: +#line 3218 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtFloat); } -#line 9112 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9303 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 477: -#line 3130 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 486: +#line 3224 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtFloat, true); } -#line 9123 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9314 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 478: -#line 3136 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 487: +#line 3230 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float subpass input", parseContext.symbolTable.atBuiltInLevel()); parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); @@ -9165,11 +9322,11 @@ yyreduce: (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtFloat16); } -#line 9135 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9326 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 479: -#line 3143 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 488: +#line 3237 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float subpass input", parseContext.symbolTable.atBuiltInLevel()); parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); @@ -9177,98 +9334,98 @@ yyreduce: (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtFloat16, true); } -#line 9147 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9338 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 480: -#line 3150 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 489: +#line 3244 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtInt); } -#line 9158 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9349 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 481: -#line 3156 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 490: +#line 3250 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtInt, true); } -#line 9169 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9360 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 482: -#line 3162 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 491: +#line 3256 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtUint); } -#line 9180 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9371 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 483: -#line 3168 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 492: +#line 3262 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtUint, true); } -#line 9191 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9382 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 484: -#line 3174 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 493: +#line 3268 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.fcoopmatCheck((yyvsp[0].lex).loc, "fcoopmatNV", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).coopmat = true; } -#line 9202 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9393 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 485: -#line 3180 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 494: +#line 3274 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.intcoopmatCheck((yyvsp[0].lex).loc, "icoopmatNV", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; (yyval.interm.type).coopmat = true; } -#line 9213 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9404 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 486: -#line 3186 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 495: +#line 3280 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.intcoopmatCheck((yyvsp[0].lex).loc, "ucoopmatNV", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; (yyval.interm.type).coopmat = true; } -#line 9224 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9415 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 487: -#line 3193 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 496: +#line 3287 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type) = (yyvsp[0].interm.type); (yyval.interm.type).qualifier.storage = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; parseContext.structTypeCheck((yyval.interm.type).loc, (yyval.interm.type)); } -#line 9234 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9425 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 488: -#line 3198 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 497: +#line 3292 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // // This is for user defined type names. The lexical phase looked up the @@ -9282,47 +9439,47 @@ yyreduce: } else parseContext.error((yyvsp[0].lex).loc, "expected type name", (yyvsp[0].lex).string->c_str(), ""); } -#line 9252 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9443 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 489: -#line 3214 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 498: +#line 3308 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "highp precision qualifier"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); parseContext.handlePrecisionQualifier((yyvsp[0].lex).loc, (yyval.interm.type).qualifier, EpqHigh); } -#line 9262 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9453 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 490: -#line 3219 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 499: +#line 3313 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "mediump precision qualifier"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); parseContext.handlePrecisionQualifier((yyvsp[0].lex).loc, (yyval.interm.type).qualifier, EpqMedium); } -#line 9272 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9463 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 491: -#line 3224 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 500: +#line 3318 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "lowp precision qualifier"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); parseContext.handlePrecisionQualifier((yyvsp[0].lex).loc, (yyval.interm.type).qualifier, EpqLow); } -#line 9282 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9473 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 492: -#line 3232 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 501: +#line 3326 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.nestedStructCheck((yyvsp[-2].lex).loc); } -#line 9288 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9479 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 493: -#line 3232 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 502: +#line 3326 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { TType* structure = new TType((yyvsp[-1].interm.typeList), *(yyvsp[-4].lex).string); parseContext.structArrayCheck((yyvsp[-4].lex).loc, *structure); @@ -9334,17 +9491,17 @@ yyreduce: (yyval.interm.type).userDef = structure; --parseContext.structNestingLevel; } -#line 9304 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9495 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 494: -#line 3243 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 503: +#line 3337 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.nestedStructCheck((yyvsp[-1].lex).loc); } -#line 9310 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9501 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 495: -#line 3243 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 504: +#line 3337 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { TType* structure = new TType((yyvsp[-1].interm.typeList), TString("")); (yyval.interm.type).init((yyvsp[-4].lex).loc); @@ -9352,19 +9509,19 @@ yyreduce: (yyval.interm.type).userDef = structure; --parseContext.structNestingLevel; } -#line 9322 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9513 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 496: -#line 3253 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 505: +#line 3347 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeList) = (yyvsp[0].interm.typeList); } -#line 9330 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9521 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 497: -#line 3256 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 506: +#line 3350 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeList) = (yyvsp[-1].interm.typeList); for (unsigned int i = 0; i < (yyvsp[0].interm.typeList)->size(); ++i) { @@ -9375,11 +9532,11 @@ yyreduce: (yyval.interm.typeList)->push_back((*(yyvsp[0].interm.typeList))[i]); } } -#line 9345 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9536 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 498: -#line 3269 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 507: +#line 3363 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if ((yyvsp[-2].interm.type).arraySizes) { parseContext.profileRequires((yyvsp[-2].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); @@ -9402,11 +9559,11 @@ yyreduce: (*(yyval.interm.typeList))[i].type->shallowCopy(type); } } -#line 9372 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9563 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 499: -#line 3291 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 508: +#line 3385 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if ((yyvsp[-2].interm.type).arraySizes) { parseContext.profileRequires((yyvsp[-2].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); @@ -9431,38 +9588,38 @@ yyreduce: (*(yyval.interm.typeList))[i].type->shallowCopy(type); } } -#line 9401 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9592 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 500: -#line 3318 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 509: +#line 3412 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeList) = new TTypeList; (yyval.interm.typeList)->push_back((yyvsp[0].interm.typeLine)); } -#line 9410 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9601 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 501: -#line 3322 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 510: +#line 3416 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeList)->push_back((yyvsp[0].interm.typeLine)); } -#line 9418 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9609 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 502: -#line 3328 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 511: +#line 3422 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeLine).type = new TType(EbtVoid); (yyval.interm.typeLine).loc = (yyvsp[0].lex).loc; (yyval.interm.typeLine).type->setFieldName(*(yyvsp[0].lex).string); } -#line 9428 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9619 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 503: -#line 3333 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 512: +#line 3427 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.arrayOfArrayVersionCheck((yyvsp[-1].lex).loc, (yyvsp[0].interm).arraySizes); @@ -9471,235 +9628,235 @@ yyreduce: (yyval.interm.typeLine).type->setFieldName(*(yyvsp[-1].lex).string); (yyval.interm.typeLine).type->transferArraySizes((yyvsp[0].interm).arraySizes); } -#line 9441 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9632 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 504: -#line 3344 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 513: +#line 3438 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 9449 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9640 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 505: -#line 3348 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 514: +#line 3442 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { const char* initFeature = "{ } style initializers"; parseContext.requireProfile((yyvsp[-2].lex).loc, ~EEsProfile, initFeature); parseContext.profileRequires((yyvsp[-2].lex).loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature); (yyval.interm.intermTypedNode) = (yyvsp[-1].interm.intermTypedNode); } -#line 9460 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9651 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 506: -#line 3354 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 515: +#line 3448 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { const char* initFeature = "{ } style initializers"; parseContext.requireProfile((yyvsp[-3].lex).loc, ~EEsProfile, initFeature); parseContext.profileRequires((yyvsp[-3].lex).loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature); (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 9471 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 507: -#line 3365 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.intermTypedNode) = parseContext.intermediate.growAggregate(0, (yyvsp[0].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)->getLoc()); - } -#line 9479 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 508: -#line 3368 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.intermTypedNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); - } -#line 9487 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 509: -#line 3375 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9493 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 510: -#line 3379 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9499 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 511: -#line 3380 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9505 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 512: -#line 3386 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9511 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 513: -#line 3387 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9517 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 514: -#line 3388 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9523 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 515: -#line 3389 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9529 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9662 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 516: -#line 3390 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9535 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 3459 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.intermediate.growAggregate(0, (yyvsp[0].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)->getLoc()); + } +#line 9670 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 517: -#line 3391 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9541 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 3462 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + } +#line 9678 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 518: -#line 3392 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 3469 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9547 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9684 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 519: -#line 3394 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 3473 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9553 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9690 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 520: -#line 3400 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 3474 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 9696 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 521: +#line 3480 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 9702 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 522: +#line 3481 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 9708 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 523: +#line 3482 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 9714 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 524: +#line 3483 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 9720 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 525: +#line 3484 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 9726 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 526: +#line 3485 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 9732 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 527: +#line 3486 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 9738 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 528: +#line 3488 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 9744 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 529: +#line 3494 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireStage((yyvsp[-1].lex).loc, EShLangFragment, "demote"); parseContext.requireExtensions((yyvsp[-1].lex).loc, 1, &E_GL_EXT_demote_to_helper_invocation, "demote"); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpDemote, (yyvsp[-1].lex).loc); } -#line 9563 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9754 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 521: -#line 3409 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 530: +#line 3503 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; } -#line 9569 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9760 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 522: -#line 3410 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 531: +#line 3504 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.symbolTable.push(); ++parseContext.statementNestingLevel; } -#line 9578 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9769 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 523: -#line 3414 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 532: +#line 3508 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); --parseContext.statementNestingLevel; } -#line 9587 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9778 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 524: -#line 3418 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 533: +#line 3512 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if ((yyvsp[-2].interm.intermNode) && (yyvsp[-2].interm.intermNode)->getAsAggregate()) (yyvsp[-2].interm.intermNode)->getAsAggregate()->setOperator(EOpSequence); (yyval.interm.intermNode) = (yyvsp[-2].interm.intermNode); } -#line 9597 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9788 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 525: -#line 3426 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 534: +#line 3520 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9603 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9794 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 526: -#line 3427 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 535: +#line 3521 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9609 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9800 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 527: -#line 3431 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 536: +#line 3525 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { ++parseContext.controlFlowNestingLevel; } -#line 9617 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9808 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 528: -#line 3434 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 537: +#line 3528 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { --parseContext.controlFlowNestingLevel; (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9626 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9817 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 529: -#line 3438 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 538: +#line 3532 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.symbolTable.push(); ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 9636 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9827 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 530: -#line 3443 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 539: +#line 3537 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9647 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9838 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 531: -#line 3452 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 540: +#line 3546 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; } -#line 9655 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9846 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 532: -#line 3455 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 541: +#line 3549 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if ((yyvsp[-1].interm.intermNode) && (yyvsp[-1].interm.intermNode)->getAsAggregate()) (yyvsp[-1].interm.intermNode)->getAsAggregate()->setOperator(EOpSequence); (yyval.interm.intermNode) = (yyvsp[-1].interm.intermNode); } -#line 9665 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9856 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 533: -#line 3463 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 542: +#line 3557 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[0].interm.intermNode)); if ((yyvsp[0].interm.intermNode) && (yyvsp[0].interm.intermNode)->getAsBranchNode() && ((yyvsp[0].interm.intermNode)->getAsBranchNode()->getFlowOp() == EOpCase || @@ -9708,11 +9865,11 @@ yyreduce: (yyval.interm.intermNode) = 0; // start a fresh subsequence for what's after this case } } -#line 9678 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9869 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 534: -#line 3471 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 543: +#line 3565 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if ((yyvsp[0].interm.intermNode) && (yyvsp[0].interm.intermNode)->getAsBranchNode() && ((yyvsp[0].interm.intermNode)->getAsBranchNode()->getFlowOp() == EOpCase || (yyvsp[0].interm.intermNode)->getAsBranchNode()->getFlowOp() == EOpDefault)) { @@ -9721,76 +9878,76 @@ yyreduce: } else (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-1].interm.intermNode), (yyvsp[0].interm.intermNode)); } -#line 9691 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9882 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 535: -#line 3482 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 544: +#line 3576 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; } -#line 9697 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9888 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 536: -#line 3483 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 545: +#line 3577 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = static_cast((yyvsp[-1].interm.intermTypedNode)); } -#line 9703 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9894 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 537: -#line 3487 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 546: +#line 3581 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9711 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9902 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 538: -#line 3491 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 547: +#line 3585 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.handleSelectionAttributes(*(yyvsp[-1].interm.attributes), (yyvsp[0].interm.intermNode)); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9720 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9911 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 539: -#line 3498 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 548: +#line 3592 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.boolCheck((yyvsp[-4].lex).loc, (yyvsp[-2].interm.intermTypedNode)); (yyval.interm.intermNode) = parseContext.intermediate.addSelection((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.nodePair), (yyvsp[-4].lex).loc); } -#line 9729 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9920 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 540: -#line 3505 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 549: +#line 3599 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermNode); (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermNode); } -#line 9738 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9929 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 541: -#line 3509 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 550: +#line 3603 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.nodePair).node1 = (yyvsp[0].interm.intermNode); (yyval.interm.nodePair).node2 = 0; } -#line 9747 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9938 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 542: -#line 3517 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 551: +#line 3611 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); parseContext.boolCheck((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode)); } -#line 9756 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9947 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 543: -#line 3521 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 552: +#line 3615 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.boolCheck((yyvsp[-2].lex).loc, (yyvsp[-3].interm.type)); @@ -9801,28 +9958,28 @@ yyreduce: else (yyval.interm.intermTypedNode) = 0; } -#line 9771 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9962 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 544: -#line 3534 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 553: +#line 3628 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9779 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9970 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 545: -#line 3538 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 554: +#line 3632 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.handleSwitchAttributes(*(yyvsp[-1].interm.attributes), (yyvsp[0].interm.intermNode)); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9788 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9979 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 546: -#line 3545 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 555: +#line 3639 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // start new switch sequence on the switch stack ++parseContext.controlFlowNestingLevel; @@ -9831,11 +9988,11 @@ yyreduce: parseContext.switchLevel.push_back(parseContext.statementNestingLevel); parseContext.symbolTable.push(); } -#line 9801 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9992 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 547: -#line 3553 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 556: +#line 3647 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = parseContext.addSwitch((yyvsp[-7].lex).loc, (yyvsp[-5].interm.intermTypedNode), (yyvsp[-1].interm.intermNode) ? (yyvsp[-1].interm.intermNode)->getAsAggregate() : 0); delete parseContext.switchSequenceStack.back(); @@ -9845,27 +10002,27 @@ yyreduce: --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 9815 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10006 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 548: -#line 3565 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 557: +#line 3659 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; } -#line 9823 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10014 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 549: -#line 3568 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 558: +#line 3662 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9831 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10022 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 550: -#line 3574 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 559: +#line 3668 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; if (parseContext.switchLevel.size() == 0) @@ -9878,11 +10035,11 @@ yyreduce: (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpCase, (yyvsp[-1].interm.intermTypedNode), (yyvsp[-2].lex).loc); } } -#line 9848 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10039 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 551: -#line 3586 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 560: +#line 3680 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; if (parseContext.switchLevel.size() == 0) @@ -9892,28 +10049,28 @@ yyreduce: else (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpDefault, (yyvsp[-1].lex).loc); } -#line 9862 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10053 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 552: -#line 3598 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 561: +#line 3692 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9870 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10061 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 553: -#line 3602 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 562: +#line 3696 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.handleLoopAttributes(*(yyvsp[-1].interm.attributes), (yyvsp[0].interm.intermNode)); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9879 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10070 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 554: -#line 3609 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 563: +#line 3703 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if (! parseContext.limits.whileLoops) parseContext.error((yyvsp[-1].lex).loc, "while loops not available", "limitation", ""); @@ -9922,11 +10079,11 @@ yyreduce: ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 9892 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10083 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 555: -#line 3617 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 564: +#line 3711 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); (yyval.interm.intermNode) = parseContext.intermediate.addLoop((yyvsp[0].interm.intermNode), (yyvsp[-2].interm.intermTypedNode), 0, true, (yyvsp[-5].lex).loc); @@ -9934,21 +10091,21 @@ yyreduce: --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 9904 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10095 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 556: -#line 3624 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 565: +#line 3718 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { ++parseContext.loopNestingLevel; ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 9914 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10105 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 557: -#line 3629 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 566: +#line 3723 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if (! parseContext.limits.whileLoops) parseContext.error((yyvsp[-7].lex).loc, "do-while loops not available", "limitation", ""); @@ -9960,22 +10117,22 @@ yyreduce: --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 9930 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10121 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 558: -#line 3640 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 567: +#line 3734 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 9941 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10132 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 559: -#line 3646 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 568: +#line 3740 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[-3].interm.intermNode), (yyvsp[-5].lex).loc); @@ -9988,81 +10145,81 @@ yyreduce: --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 9958 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10149 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 560: -#line 3661 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 569: +#line 3755 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9966 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10157 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 561: -#line 3664 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 570: +#line 3758 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9974 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10165 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 562: -#line 3670 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 571: +#line 3764 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 9982 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10173 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 563: -#line 3673 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 572: +#line 3767 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = 0; } -#line 9990 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10181 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 564: -#line 3679 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 573: +#line 3773 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.nodePair).node1 = (yyvsp[-1].interm.intermTypedNode); (yyval.interm.nodePair).node2 = 0; } -#line 9999 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10190 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 565: -#line 3683 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 574: +#line 3777 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermTypedNode); (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermTypedNode); } -#line 10008 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10199 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 566: -#line 3690 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 575: +#line 3784 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if (parseContext.loopNestingLevel <= 0) parseContext.error((yyvsp[-1].lex).loc, "continue statement only allowed in loops", "", ""); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpContinue, (yyvsp[-1].lex).loc); } -#line 10018 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10209 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 567: -#line 3695 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 576: +#line 3789 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if (parseContext.loopNestingLevel + parseContext.switchSequenceStack.size() <= 0) parseContext.error((yyvsp[-1].lex).loc, "break statement only allowed in switch and loops", "", ""); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpBreak, (yyvsp[-1].lex).loc); } -#line 10028 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10219 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 568: -#line 3700 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 577: +#line 3794 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpReturn, (yyvsp[-1].lex).loc); if (parseContext.currentFunctionType->getBasicType() != EbtVoid) @@ -10070,83 +10227,91 @@ yyreduce: if (parseContext.inMain) parseContext.postEntryPointReturn = true; } -#line 10040 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10231 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 569: -#line 3707 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 578: +#line 3801 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = parseContext.handleReturnValue((yyvsp[-2].lex).loc, (yyvsp[-1].interm.intermTypedNode)); } -#line 10048 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10239 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 570: -#line 3710 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 579: +#line 3804 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireStage((yyvsp[-1].lex).loc, EShLangFragment, "discard"); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpKill, (yyvsp[-1].lex).loc); } -#line 10057 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10248 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 571: -#line 3719 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 580: +#line 3813 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); parseContext.intermediate.setTreeRoot((yyval.interm.intermNode)); } -#line 10066 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10257 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 572: -#line 3723 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 581: +#line 3817 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if ((yyvsp[0].interm.intermNode) != nullptr) { (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-1].interm.intermNode), (yyvsp[0].interm.intermNode)); parseContext.intermediate.setTreeRoot((yyval.interm.intermNode)); } } -#line 10077 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10268 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 573: -#line 3732 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 582: +#line 3826 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 10085 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10276 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 574: -#line 3735 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 583: +#line 3829 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 10093 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10284 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 575: -#line 3739 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 584: +#line 3833 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireProfile((yyvsp[0].lex).loc, ~EEsProfile, "extraneous semicolon"); parseContext.profileRequires((yyvsp[0].lex).loc, ~EEsProfile, 460, nullptr, "extraneous semicolon"); (yyval.interm.intermNode) = nullptr; } -#line 10103 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10294 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 576: -#line 3748 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 585: +#line 3842 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyvsp[0].interm).function = parseContext.handleFunctionDeclarator((yyvsp[0].interm).loc, *(yyvsp[0].interm).function, false /* not prototype */); (yyvsp[0].interm).intermNode = parseContext.handleFunctionDefinition((yyvsp[0].interm).loc, *(yyvsp[0].interm).function); + + // For ES 100 only, according to ES shading language 100 spec: A function + // body has a scope nested inside the function's definition. + if (parseContext.profile == EEsProfile && parseContext.version == 100) + { + parseContext.symbolTable.push(); + ++parseContext.statementNestingLevel; + } } -#line 10112 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10311 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 577: -#line 3752 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 586: +#line 3854 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // May be best done as post process phase on intermediate code if (parseContext.currentFunctionType->getBasicType() != EbtVoid && ! parseContext.functionReturnsValue) @@ -10161,53 +10326,64 @@ yyreduce: (yyval.interm.intermNode)->getAsAggregate()->setOptimize(parseContext.contextPragma.optimize); (yyval.interm.intermNode)->getAsAggregate()->setDebug(parseContext.contextPragma.debug); (yyval.interm.intermNode)->getAsAggregate()->setPragmaTable(parseContext.contextPragma.pragmaTable); + + // Set currentFunctionType to empty pointer when goes outside of the function + parseContext.currentFunctionType = nullptr; + + // For ES 100 only, according to ES shading language 100 spec: A function + // body has a scope nested inside the function's definition. + if (parseContext.profile == EEsProfile && parseContext.version == 100) + { + parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + --parseContext.statementNestingLevel; + } } -#line 10132 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10342 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 578: -#line 3771 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 587: +#line 3884 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.attributes) = (yyvsp[-2].interm.attributes); parseContext.requireExtensions((yyvsp[-4].lex).loc, 1, &E_GL_EXT_control_flow_attributes, "attribute"); } -#line 10141 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10351 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 579: -#line 3777 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 588: +#line 3890 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.attributes) = (yyvsp[0].interm.attributes); } -#line 10149 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10359 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 580: -#line 3780 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 589: +#line 3893 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.attributes) = parseContext.mergeAttributes((yyvsp[-2].interm.attributes), (yyvsp[0].interm.attributes)); } -#line 10157 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10367 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 581: -#line 3785 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 590: +#line 3898 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.attributes) = parseContext.makeAttributes(*(yyvsp[0].lex).string); } -#line 10165 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10375 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 582: -#line 3788 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 591: +#line 3901 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.attributes) = parseContext.makeAttributes(*(yyvsp[-3].lex).string, (yyvsp[-1].interm.intermTypedNode)); } -#line 10173 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10383 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; -#line 10177 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10387 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -10435,5 +10611,5 @@ yyreturn: #endif return yyresult; } -#line 3793 "MachineIndependent/glslang.y" /* yacc.c:1906 */ +#line 3906 "MachineIndependent/glslang.y" /* yacc.c:1906 */ diff --git a/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp.h b/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp.h index f4f411473..78b72a246 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp.h +++ b/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp.h @@ -203,256 +203,265 @@ extern int yydebug; F64MAT4X4 = 413, ATOMIC_UINT = 414, ACCSTRUCTNV = 415, - FCOOPMATNV = 416, - ICOOPMATNV = 417, - UCOOPMATNV = 418, - SAMPLERCUBEARRAY = 419, - SAMPLERCUBEARRAYSHADOW = 420, - ISAMPLERCUBEARRAY = 421, - USAMPLERCUBEARRAY = 422, - SAMPLER1D = 423, - SAMPLER1DARRAY = 424, - SAMPLER1DARRAYSHADOW = 425, - ISAMPLER1D = 426, - SAMPLER1DSHADOW = 427, - SAMPLER2DRECT = 428, - SAMPLER2DRECTSHADOW = 429, - ISAMPLER2DRECT = 430, - USAMPLER2DRECT = 431, - SAMPLERBUFFER = 432, - ISAMPLERBUFFER = 433, - USAMPLERBUFFER = 434, - SAMPLER2DMS = 435, - ISAMPLER2DMS = 436, - USAMPLER2DMS = 437, - SAMPLER2DMSARRAY = 438, - ISAMPLER2DMSARRAY = 439, - USAMPLER2DMSARRAY = 440, - SAMPLEREXTERNALOES = 441, - SAMPLEREXTERNAL2DY2YEXT = 442, - ISAMPLER1DARRAY = 443, - USAMPLER1D = 444, - USAMPLER1DARRAY = 445, - F16SAMPLER1D = 446, - F16SAMPLER2D = 447, - F16SAMPLER3D = 448, - F16SAMPLER2DRECT = 449, - F16SAMPLERCUBE = 450, - F16SAMPLER1DARRAY = 451, - F16SAMPLER2DARRAY = 452, - F16SAMPLERCUBEARRAY = 453, - F16SAMPLERBUFFER = 454, - F16SAMPLER2DMS = 455, - F16SAMPLER2DMSARRAY = 456, - F16SAMPLER1DSHADOW = 457, - F16SAMPLER2DSHADOW = 458, - F16SAMPLER1DARRAYSHADOW = 459, - F16SAMPLER2DARRAYSHADOW = 460, - F16SAMPLER2DRECTSHADOW = 461, - F16SAMPLERCUBESHADOW = 462, - F16SAMPLERCUBEARRAYSHADOW = 463, - IMAGE1D = 464, - IIMAGE1D = 465, - UIMAGE1D = 466, - IMAGE2D = 467, - IIMAGE2D = 468, - UIMAGE2D = 469, - IMAGE3D = 470, - IIMAGE3D = 471, - UIMAGE3D = 472, - IMAGE2DRECT = 473, - IIMAGE2DRECT = 474, - UIMAGE2DRECT = 475, - IMAGECUBE = 476, - IIMAGECUBE = 477, - UIMAGECUBE = 478, - IMAGEBUFFER = 479, - IIMAGEBUFFER = 480, - UIMAGEBUFFER = 481, - IMAGE1DARRAY = 482, - IIMAGE1DARRAY = 483, - UIMAGE1DARRAY = 484, - IMAGE2DARRAY = 485, - IIMAGE2DARRAY = 486, - UIMAGE2DARRAY = 487, - IMAGECUBEARRAY = 488, - IIMAGECUBEARRAY = 489, - UIMAGECUBEARRAY = 490, - IMAGE2DMS = 491, - IIMAGE2DMS = 492, - UIMAGE2DMS = 493, - IMAGE2DMSARRAY = 494, - IIMAGE2DMSARRAY = 495, - UIMAGE2DMSARRAY = 496, - F16IMAGE1D = 497, - F16IMAGE2D = 498, - F16IMAGE3D = 499, - F16IMAGE2DRECT = 500, - F16IMAGECUBE = 501, - F16IMAGE1DARRAY = 502, - F16IMAGE2DARRAY = 503, - F16IMAGECUBEARRAY = 504, - F16IMAGEBUFFER = 505, - F16IMAGE2DMS = 506, - F16IMAGE2DMSARRAY = 507, - TEXTURECUBEARRAY = 508, - ITEXTURECUBEARRAY = 509, - UTEXTURECUBEARRAY = 510, - TEXTURE1D = 511, - ITEXTURE1D = 512, - UTEXTURE1D = 513, - TEXTURE1DARRAY = 514, - ITEXTURE1DARRAY = 515, - UTEXTURE1DARRAY = 516, - TEXTURE2DRECT = 517, - ITEXTURE2DRECT = 518, - UTEXTURE2DRECT = 519, - TEXTUREBUFFER = 520, - ITEXTUREBUFFER = 521, - UTEXTUREBUFFER = 522, - TEXTURE2DMS = 523, - ITEXTURE2DMS = 524, - UTEXTURE2DMS = 525, - TEXTURE2DMSARRAY = 526, - ITEXTURE2DMSARRAY = 527, - UTEXTURE2DMSARRAY = 528, - F16TEXTURE1D = 529, - F16TEXTURE2D = 530, - F16TEXTURE3D = 531, - F16TEXTURE2DRECT = 532, - F16TEXTURECUBE = 533, - F16TEXTURE1DARRAY = 534, - F16TEXTURE2DARRAY = 535, - F16TEXTURECUBEARRAY = 536, - F16TEXTUREBUFFER = 537, - F16TEXTURE2DMS = 538, - F16TEXTURE2DMSARRAY = 539, - SUBPASSINPUT = 540, - SUBPASSINPUTMS = 541, - ISUBPASSINPUT = 542, - ISUBPASSINPUTMS = 543, - USUBPASSINPUT = 544, - USUBPASSINPUTMS = 545, - F16SUBPASSINPUT = 546, - F16SUBPASSINPUTMS = 547, - LEFT_OP = 548, - RIGHT_OP = 549, - INC_OP = 550, - DEC_OP = 551, - LE_OP = 552, - GE_OP = 553, - EQ_OP = 554, - NE_OP = 555, - AND_OP = 556, - OR_OP = 557, - XOR_OP = 558, - MUL_ASSIGN = 559, - DIV_ASSIGN = 560, - ADD_ASSIGN = 561, - MOD_ASSIGN = 562, - LEFT_ASSIGN = 563, - RIGHT_ASSIGN = 564, - AND_ASSIGN = 565, - XOR_ASSIGN = 566, - OR_ASSIGN = 567, - SUB_ASSIGN = 568, - LEFT_PAREN = 569, - RIGHT_PAREN = 570, - LEFT_BRACKET = 571, - RIGHT_BRACKET = 572, - LEFT_BRACE = 573, - RIGHT_BRACE = 574, - DOT = 575, - COMMA = 576, - COLON = 577, - EQUAL = 578, - SEMICOLON = 579, - BANG = 580, - DASH = 581, - TILDE = 582, - PLUS = 583, - STAR = 584, - SLASH = 585, - PERCENT = 586, - LEFT_ANGLE = 587, - RIGHT_ANGLE = 588, - VERTICAL_BAR = 589, - CARET = 590, - AMPERSAND = 591, - QUESTION = 592, - INVARIANT = 593, - HIGH_PRECISION = 594, - MEDIUM_PRECISION = 595, - LOW_PRECISION = 596, - PRECISION = 597, - PACKED = 598, - RESOURCE = 599, - SUPERP = 600, - FLOATCONSTANT = 601, - INTCONSTANT = 602, - UINTCONSTANT = 603, - BOOLCONSTANT = 604, - IDENTIFIER = 605, - TYPE_NAME = 606, - CENTROID = 607, - IN = 608, - OUT = 609, - INOUT = 610, - STRUCT = 611, - VOID = 612, - WHILE = 613, - BREAK = 614, - CONTINUE = 615, - DO = 616, - ELSE = 617, - FOR = 618, - IF = 619, - DISCARD = 620, - RETURN = 621, - SWITCH = 622, - CASE = 623, - DEFAULT = 624, - UNIFORM = 625, - SHARED = 626, - BUFFER = 627, - FLAT = 628, - SMOOTH = 629, - LAYOUT = 630, - DOUBLECONSTANT = 631, - INT16CONSTANT = 632, - UINT16CONSTANT = 633, - FLOAT16CONSTANT = 634, - INT32CONSTANT = 635, - UINT32CONSTANT = 636, - INT64CONSTANT = 637, - UINT64CONSTANT = 638, - SUBROUTINE = 639, - DEMOTE = 640, - PAYLOADNV = 641, - PAYLOADINNV = 642, - HITATTRNV = 643, - CALLDATANV = 644, - CALLDATAINNV = 645, - PATCH = 646, - SAMPLE = 647, - NONUNIFORM = 648, - COHERENT = 649, - VOLATILE = 650, - RESTRICT = 651, - READONLY = 652, - WRITEONLY = 653, - DEVICECOHERENT = 654, - QUEUEFAMILYCOHERENT = 655, - WORKGROUPCOHERENT = 656, - SUBGROUPCOHERENT = 657, - NONPRIVATE = 658, - NOPERSPECTIVE = 659, - EXPLICITINTERPAMD = 660, - PERVERTEXNV = 661, - PERPRIMITIVENV = 662, - PERVIEWNV = 663, - PERTASKNV = 664, - PRECISE = 665 + ACCSTRUCTEXT = 416, + RAYQUERYEXT = 417, + FCOOPMATNV = 418, + ICOOPMATNV = 419, + UCOOPMATNV = 420, + SAMPLERCUBEARRAY = 421, + SAMPLERCUBEARRAYSHADOW = 422, + ISAMPLERCUBEARRAY = 423, + USAMPLERCUBEARRAY = 424, + SAMPLER1D = 425, + SAMPLER1DARRAY = 426, + SAMPLER1DARRAYSHADOW = 427, + ISAMPLER1D = 428, + SAMPLER1DSHADOW = 429, + SAMPLER2DRECT = 430, + SAMPLER2DRECTSHADOW = 431, + ISAMPLER2DRECT = 432, + USAMPLER2DRECT = 433, + SAMPLERBUFFER = 434, + ISAMPLERBUFFER = 435, + USAMPLERBUFFER = 436, + SAMPLER2DMS = 437, + ISAMPLER2DMS = 438, + USAMPLER2DMS = 439, + SAMPLER2DMSARRAY = 440, + ISAMPLER2DMSARRAY = 441, + USAMPLER2DMSARRAY = 442, + SAMPLEREXTERNALOES = 443, + SAMPLEREXTERNAL2DY2YEXT = 444, + ISAMPLER1DARRAY = 445, + USAMPLER1D = 446, + USAMPLER1DARRAY = 447, + F16SAMPLER1D = 448, + F16SAMPLER2D = 449, + F16SAMPLER3D = 450, + F16SAMPLER2DRECT = 451, + F16SAMPLERCUBE = 452, + F16SAMPLER1DARRAY = 453, + F16SAMPLER2DARRAY = 454, + F16SAMPLERCUBEARRAY = 455, + F16SAMPLERBUFFER = 456, + F16SAMPLER2DMS = 457, + F16SAMPLER2DMSARRAY = 458, + F16SAMPLER1DSHADOW = 459, + F16SAMPLER2DSHADOW = 460, + F16SAMPLER1DARRAYSHADOW = 461, + F16SAMPLER2DARRAYSHADOW = 462, + F16SAMPLER2DRECTSHADOW = 463, + F16SAMPLERCUBESHADOW = 464, + F16SAMPLERCUBEARRAYSHADOW = 465, + IMAGE1D = 466, + IIMAGE1D = 467, + UIMAGE1D = 468, + IMAGE2D = 469, + IIMAGE2D = 470, + UIMAGE2D = 471, + IMAGE3D = 472, + IIMAGE3D = 473, + UIMAGE3D = 474, + IMAGE2DRECT = 475, + IIMAGE2DRECT = 476, + UIMAGE2DRECT = 477, + IMAGECUBE = 478, + IIMAGECUBE = 479, + UIMAGECUBE = 480, + IMAGEBUFFER = 481, + IIMAGEBUFFER = 482, + UIMAGEBUFFER = 483, + IMAGE1DARRAY = 484, + IIMAGE1DARRAY = 485, + UIMAGE1DARRAY = 486, + IMAGE2DARRAY = 487, + IIMAGE2DARRAY = 488, + UIMAGE2DARRAY = 489, + IMAGECUBEARRAY = 490, + IIMAGECUBEARRAY = 491, + UIMAGECUBEARRAY = 492, + IMAGE2DMS = 493, + IIMAGE2DMS = 494, + UIMAGE2DMS = 495, + IMAGE2DMSARRAY = 496, + IIMAGE2DMSARRAY = 497, + UIMAGE2DMSARRAY = 498, + F16IMAGE1D = 499, + F16IMAGE2D = 500, + F16IMAGE3D = 501, + F16IMAGE2DRECT = 502, + F16IMAGECUBE = 503, + F16IMAGE1DARRAY = 504, + F16IMAGE2DARRAY = 505, + F16IMAGECUBEARRAY = 506, + F16IMAGEBUFFER = 507, + F16IMAGE2DMS = 508, + F16IMAGE2DMSARRAY = 509, + TEXTURECUBEARRAY = 510, + ITEXTURECUBEARRAY = 511, + UTEXTURECUBEARRAY = 512, + TEXTURE1D = 513, + ITEXTURE1D = 514, + UTEXTURE1D = 515, + TEXTURE1DARRAY = 516, + ITEXTURE1DARRAY = 517, + UTEXTURE1DARRAY = 518, + TEXTURE2DRECT = 519, + ITEXTURE2DRECT = 520, + UTEXTURE2DRECT = 521, + TEXTUREBUFFER = 522, + ITEXTUREBUFFER = 523, + UTEXTUREBUFFER = 524, + TEXTURE2DMS = 525, + ITEXTURE2DMS = 526, + UTEXTURE2DMS = 527, + TEXTURE2DMSARRAY = 528, + ITEXTURE2DMSARRAY = 529, + UTEXTURE2DMSARRAY = 530, + F16TEXTURE1D = 531, + F16TEXTURE2D = 532, + F16TEXTURE3D = 533, + F16TEXTURE2DRECT = 534, + F16TEXTURECUBE = 535, + F16TEXTURE1DARRAY = 536, + F16TEXTURE2DARRAY = 537, + F16TEXTURECUBEARRAY = 538, + F16TEXTUREBUFFER = 539, + F16TEXTURE2DMS = 540, + F16TEXTURE2DMSARRAY = 541, + SUBPASSINPUT = 542, + SUBPASSINPUTMS = 543, + ISUBPASSINPUT = 544, + ISUBPASSINPUTMS = 545, + USUBPASSINPUT = 546, + USUBPASSINPUTMS = 547, + F16SUBPASSINPUT = 548, + F16SUBPASSINPUTMS = 549, + LEFT_OP = 550, + RIGHT_OP = 551, + INC_OP = 552, + DEC_OP = 553, + LE_OP = 554, + GE_OP = 555, + EQ_OP = 556, + NE_OP = 557, + AND_OP = 558, + OR_OP = 559, + XOR_OP = 560, + MUL_ASSIGN = 561, + DIV_ASSIGN = 562, + ADD_ASSIGN = 563, + MOD_ASSIGN = 564, + LEFT_ASSIGN = 565, + RIGHT_ASSIGN = 566, + AND_ASSIGN = 567, + XOR_ASSIGN = 568, + OR_ASSIGN = 569, + SUB_ASSIGN = 570, + STRING_LITERAL = 571, + LEFT_PAREN = 572, + RIGHT_PAREN = 573, + LEFT_BRACKET = 574, + RIGHT_BRACKET = 575, + LEFT_BRACE = 576, + RIGHT_BRACE = 577, + DOT = 578, + COMMA = 579, + COLON = 580, + EQUAL = 581, + SEMICOLON = 582, + BANG = 583, + DASH = 584, + TILDE = 585, + PLUS = 586, + STAR = 587, + SLASH = 588, + PERCENT = 589, + LEFT_ANGLE = 590, + RIGHT_ANGLE = 591, + VERTICAL_BAR = 592, + CARET = 593, + AMPERSAND = 594, + QUESTION = 595, + INVARIANT = 596, + HIGH_PRECISION = 597, + MEDIUM_PRECISION = 598, + LOW_PRECISION = 599, + PRECISION = 600, + PACKED = 601, + RESOURCE = 602, + SUPERP = 603, + FLOATCONSTANT = 604, + INTCONSTANT = 605, + UINTCONSTANT = 606, + BOOLCONSTANT = 607, + IDENTIFIER = 608, + TYPE_NAME = 609, + CENTROID = 610, + IN = 611, + OUT = 612, + INOUT = 613, + STRUCT = 614, + VOID = 615, + WHILE = 616, + BREAK = 617, + CONTINUE = 618, + DO = 619, + ELSE = 620, + FOR = 621, + IF = 622, + DISCARD = 623, + RETURN = 624, + SWITCH = 625, + CASE = 626, + DEFAULT = 627, + UNIFORM = 628, + SHARED = 629, + BUFFER = 630, + FLAT = 631, + SMOOTH = 632, + LAYOUT = 633, + DOUBLECONSTANT = 634, + INT16CONSTANT = 635, + UINT16CONSTANT = 636, + FLOAT16CONSTANT = 637, + INT32CONSTANT = 638, + UINT32CONSTANT = 639, + INT64CONSTANT = 640, + UINT64CONSTANT = 641, + SUBROUTINE = 642, + DEMOTE = 643, + PAYLOADNV = 644, + PAYLOADINNV = 645, + HITATTRNV = 646, + CALLDATANV = 647, + CALLDATAINNV = 648, + PAYLOADEXT = 649, + PAYLOADINEXT = 650, + HITATTREXT = 651, + CALLDATAEXT = 652, + CALLDATAINEXT = 653, + PATCH = 654, + SAMPLE = 655, + NONUNIFORM = 656, + COHERENT = 657, + VOLATILE = 658, + RESTRICT = 659, + READONLY = 660, + WRITEONLY = 661, + DEVICECOHERENT = 662, + QUEUEFAMILYCOHERENT = 663, + WORKGROUPCOHERENT = 664, + SUBGROUPCOHERENT = 665, + NONPRIVATE = 666, + SHADERCALLCOHERENT = 667, + NOPERSPECTIVE = 668, + EXPLICITINTERPAMD = 669, + PERVERTEXNV = 670, + PERPRIMITIVENV = 671, + PERVIEWNV = 672, + PERTASKNV = 673, + PRECISE = 674 }; #endif @@ -461,7 +470,7 @@ extern int yydebug; union YYSTYPE { -#line 96 "MachineIndependent/glslang.y" /* yacc.c:1909 */ +#line 97 "MachineIndependent/glslang.y" /* yacc.c:1909 */ struct { glslang::TSourceLoc loc; @@ -497,7 +506,7 @@ union YYSTYPE glslang::TArraySizes* typeParameters; } interm; -#line 501 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */ +#line 510 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */ }; typedef union YYSTYPE YYSTYPE; diff --git a/src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp b/src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp index 3a93aedaf..f23a7058a 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp @@ -2,6 +2,7 @@ // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2016 LunarG, Inc. // Copyright (C) 2017 ARM Limited. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. // // All rights reserved. // @@ -35,7 +36,7 @@ // POSSIBILITY OF SUCH DAMAGE. // -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) #include "localintermediate.h" #include "../Include/InfoSink.h" @@ -1078,18 +1079,43 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpSubpassLoad: out.debug << "subpassLoad"; break; case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break; - case EOpTraceNV: out.debug << "traceNV"; break; - case EOpReportIntersectionNV: out.debug << "reportIntersectionNV"; break; - case EOpIgnoreIntersectionNV: out.debug << "ignoreIntersectionNV"; break; - case EOpTerminateRayNV: out.debug << "terminateRayNV"; break; - case EOpExecuteCallableNV: out.debug << "executeCallableNV"; break; + case EOpTrace: out.debug << "traceNV"; break; + case EOpReportIntersection: out.debug << "reportIntersectionNV"; break; + case EOpIgnoreIntersection: out.debug << "ignoreIntersectionNV"; break; + case EOpTerminateRay: out.debug << "terminateRayNV"; break; + case EOpExecuteCallable: out.debug << "executeCallableNV"; break; case EOpWritePackedPrimitiveIndices4x8NV: out.debug << "writePackedPrimitiveIndices4x8NV"; break; + case EOpRayQueryInitialize: out.debug << "rayQueryInitializeEXT"; break; + case EOpRayQueryTerminate: out.debug << "rayQueryTerminateEXT"; break; + case EOpRayQueryGenerateIntersection: out.debug << "rayQueryGenerateIntersectionEXT"; break; + case EOpRayQueryConfirmIntersection: out.debug << "rayQueryConfirmIntersectionEXT"; break; + case EOpRayQueryProceed: out.debug << "rayQueryProceedEXT"; break; + case EOpRayQueryGetIntersectionType: out.debug << "rayQueryGetIntersectionTypeEXT"; break; + case EOpRayQueryGetRayTMin: out.debug << "rayQueryGetRayTMinEXT"; break; + case EOpRayQueryGetRayFlags: out.debug << "rayQueryGetRayFlagsEXT"; break; + case EOpRayQueryGetIntersectionT: out.debug << "rayQueryGetIntersectionTEXT"; break; + case EOpRayQueryGetIntersectionInstanceCustomIndex: out.debug << "rayQueryGetIntersectionInstanceCustomIndexEXT"; break; + case EOpRayQueryGetIntersectionInstanceId: out.debug << "rayQueryGetIntersectionInstanceIdEXT"; break; + case EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset: out.debug << "rayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetEXT"; break; + case EOpRayQueryGetIntersectionGeometryIndex: out.debug << "rayQueryGetIntersectionGeometryIndexEXT"; break; + case EOpRayQueryGetIntersectionPrimitiveIndex: out.debug << "rayQueryGetIntersectionPrimitiveIndexEXT"; break; + case EOpRayQueryGetIntersectionBarycentrics: out.debug << "rayQueryGetIntersectionBarycentricsEXT"; break; + case EOpRayQueryGetIntersectionFrontFace: out.debug << "rayQueryGetIntersectionFrontFaceEXT"; break; + case EOpRayQueryGetIntersectionCandidateAABBOpaque: out.debug << "rayQueryGetIntersectionCandidateAABBOpaqueEXT"; break; + case EOpRayQueryGetIntersectionObjectRayDirection: out.debug << "rayQueryGetIntersectionObjectRayDirectionEXT"; break; + case EOpRayQueryGetIntersectionObjectRayOrigin: out.debug << "rayQueryGetIntersectionObjectRayOriginEXT"; break; + case EOpRayQueryGetWorldRayDirection: out.debug << "rayQueryGetWorldRayDirectionEXT"; break; + case EOpRayQueryGetWorldRayOrigin: out.debug << "rayQueryGetWorldRayOriginEXT"; break; + case EOpRayQueryGetIntersectionObjectToWorld: out.debug << "rayQueryGetIntersectionObjectToWorldEXT"; break; + case EOpRayQueryGetIntersectionWorldToObject: out.debug << "rayQueryGetIntersectionWorldToObjectEXT"; break; + case EOpCooperativeMatrixLoad: out.debug << "Load cooperative matrix"; break; case EOpCooperativeMatrixStore: out.debug << "Store cooperative matrix"; break; case EOpCooperativeMatrixMulAdd: out.debug << "MulAdd cooperative matrices"; break; case EOpIsHelperInvocation: out.debug << "IsHelperInvocation"; break; + case EOpDebugPrintf: out.debug << "Debug printf"; break; default: out.debug.message(EPrefixError, "Bad aggregation op"); } @@ -1536,4 +1562,4 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree) } // end namespace glslang -#endif // not GLSLANG_WEB \ No newline at end of file +#endif // !GLSLANG_WEB && !GLSLANG_ANGLE diff --git a/src/libraries/glslang/glslang/MachineIndependent/iomapper.cpp b/src/libraries/glslang/glslang/MachineIndependent/iomapper.cpp index 3262c0a20..905cf65d6 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/iomapper.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/iomapper.cpp @@ -33,7 +33,7 @@ // POSSIBILITY OF SUCH DAMAGE. // -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) #include "../Include/Common.h" #include "../Include/InfoSink.h" @@ -79,6 +79,11 @@ public: target = &outputList; else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().isPushConstant()) target = &uniformList; + // If a global is being visited, then we should also traverse it incase it's evaluation + // ends up visiting inputs we want to tag as live + else if (base->getQualifier().storage == EvqGlobal) + addGlobalReference(base->getName()); + if (target) { TVarEntryInfo ent = {base->getId(), base, ! traverseAll}; ent.stage = intermediate.getStage(); @@ -161,7 +166,7 @@ struct TNotifyUniformAdaptor } private: - TNotifyUniformAdaptor& operator=(TNotifyUniformAdaptor&); + TNotifyUniformAdaptor& operator=(TNotifyUniformAdaptor&) = delete; }; struct TNotifyInOutAdaptor @@ -180,7 +185,7 @@ struct TNotifyInOutAdaptor } private: - TNotifyInOutAdaptor& operator=(TNotifyInOutAdaptor&); + TNotifyInOutAdaptor& operator=(TNotifyInOutAdaptor&) = delete; }; struct TResolverUniformAdaptor { @@ -236,7 +241,7 @@ struct TResolverUniformAdaptor { bool& error; private: - TResolverUniformAdaptor& operator=(TResolverUniformAdaptor&); + TResolverUniformAdaptor& operator=(TResolverUniformAdaptor&) = delete; }; struct TResolverInOutAdaptor { @@ -283,7 +288,7 @@ struct TResolverInOutAdaptor { bool& error; private: - TResolverInOutAdaptor& operator=(TResolverInOutAdaptor&); + TResolverInOutAdaptor& operator=(TResolverInOutAdaptor&) = delete; }; // The class is used for reserving explicit uniform locations and ubo/ssbo/opaque bindings @@ -309,26 +314,43 @@ struct TSymbolValidater TIntermSymbol* base = ent1.symbol; const TType& type = ent1.symbol->getType(); const TString& name = entKey.first; - TString mangleName1, mangleName2; - type.appendMangledName(mangleName1); EShLanguage stage = ent1.stage; + TString mangleName1, mangleName2; if (currentStage != stage) { preStage = currentStage; currentStage = stage; nextStage = EShLangCount; for (int i = currentStage + 1; i < EShLangCount; i++) { - if (inVarMaps[i] != nullptr) + if (inVarMaps[i] != nullptr) { nextStage = static_cast(i); + break; + } } } + + if (type.getQualifier().isArrayedIo(stage)) { + TType subType(type, 0); + subType.appendMangledName(mangleName1); + } else { + type.appendMangledName(mangleName1); + } + if (base->getQualifier().storage == EvqVaryingIn) { // validate stage in; if (preStage == EShLangCount) return; + if (name == "gl_PerVertex") + return; if (outVarMaps[preStage] != nullptr) { auto ent2 = outVarMaps[preStage]->find(name); if (ent2 != outVarMaps[preStage]->end()) { - ent2->second.symbol->getType().appendMangledName(mangleName2); + if (ent2->second.symbol->getType().getQualifier().isArrayedIo(preStage)) { + TType subType(ent2->second.symbol->getType(), 0); + subType.appendMangledName(mangleName2); + } + else { + ent2->second.symbol->getType().appendMangledName(mangleName2); + } if (mangleName1 == mangleName2) return; else { @@ -343,10 +365,18 @@ struct TSymbolValidater // validate stage out; if (nextStage == EShLangCount) return; + if (name == "gl_PerVertex") + return; if (outVarMaps[nextStage] != nullptr) { auto ent2 = inVarMaps[nextStage]->find(name); if (ent2 != inVarMaps[nextStage]->end()) { - ent2->second.symbol->getType().appendMangledName(mangleName2); + if (ent2->second.symbol->getType().getQualifier().isArrayedIo(nextStage)) { + TType subType(ent2->second.symbol->getType(), 0); + subType.appendMangledName(mangleName2); + } + else { + ent2->second.symbol->getType().appendMangledName(mangleName2); + } if (mangleName1 == mangleName2) return; else { @@ -384,7 +414,7 @@ struct TSymbolValidater bool& hadError; private: - TSymbolValidater& operator=(TSymbolValidater&); + TSymbolValidater& operator=(TSymbolValidater&) = delete; }; struct TSlotCollector { @@ -398,7 +428,7 @@ struct TSlotCollector { TInfoSink& infoSink; private: - TSlotCollector& operator=(TSlotCollector&); + TSlotCollector& operator=(TSlotCollector&) = delete; }; TDefaultIoResolverBase::TDefaultIoResolverBase(const TIntermediate& intermediate) @@ -579,7 +609,7 @@ TDefaultGlslIoResolver::TDefaultGlslIoResolver(const TIntermediate& intermediate int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) { const TType& type = ent.symbol->getType(); - const TString& name = ent.symbol->getName(); + const TString& name = getAccessName(ent.symbol); if (currentStage != stage) { preStage = currentStage; currentStage = stage; @@ -627,7 +657,7 @@ int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInf TVarSlotMap::iterator iter = storageSlotMap[resourceKey].find(name); if (iter != storageSlotMap[resourceKey].end()) { // If interface resource be found, set it has location and this symbol's new location - // equal the symbol's explicit location declarated in pre or next stage. + // equal the symbol's explicit location declaration in pre or next stage. // // vs: out vec4 a; // fs: layout(..., location = 3,...) in vec4 a; @@ -663,7 +693,7 @@ int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInf int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) { const TType& type = ent.symbol->getType(); - const TString& name = ent.symbol->getName(); + const TString& name = getAccessName(ent.symbol); // kick out of not doing this if (! doAutoLocationMapping()) { return ent.newLocation = -1; @@ -706,7 +736,7 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn TVarSlotMap::iterator iter = slotMap.find(name); if (iter != slotMap.end()) { // If uniform resource be found, set it has location and this symbol's new location - // equal the uniform's explicit location declarated in other stage. + // equal the uniform's explicit location declaration in other stage. // // vs: uniform vec4 a; // fs: layout(..., location = 3,...) uniform vec4 a; @@ -714,7 +744,7 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn location = iter->second; } if (! hasLocation) { - // No explicit location declaraten in other stage. + // No explicit location declaration in other stage. // So we should find a new slot for this uniform. // // vs: uniform vec4 a; @@ -723,7 +753,7 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn storageSlotMap[resourceKey][name] = location; } } else { - // the first uniform declarated in a program. + // the first uniform declaration in a program. TVarSlotMap varSlotMap; location = getFreeSlot(resourceKey, 0, size); varSlotMap[name] = location; @@ -734,8 +764,8 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn int TDefaultGlslIoResolver::resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) { const TType& type = ent.symbol->getType(); - const TString& name = ent.symbol->getName(); - // On OpenGL arrays of opaque types take a seperate binding for each element + const TString& name = getAccessName(ent.symbol); + // On OpenGL arrays of opaque types take a separate binding for each element int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1; TResourceType resource = getResourceType(type); // don't need to handle uniform symbol, it will be handled in resolveUniformLocation @@ -809,7 +839,7 @@ void TDefaultGlslIoResolver::endCollect(EShLanguage /*stage*/) { void TDefaultGlslIoResolver::reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) { const TType& type = ent.symbol->getType(); - const TString& name = ent.symbol->getName(); + const TString& name = getAccessName(ent.symbol); TStorageQualifier storage = type.getQualifier().storage; EShLanguage stage(EShLangCount); switch (storage) { @@ -831,6 +861,7 @@ void TDefaultGlslIoResolver::reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& if (iter->second != location) { TString errorMsg = "Invalid location: " + name; infoSink.info.message(EPrefixInternalError, errorMsg.c_str()); + hasError = true; } } } @@ -856,6 +887,7 @@ void TDefaultGlslIoResolver::reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& if (iter->second != location) { TString errorMsg = "Invalid location: " + name; infoSink.info.message(EPrefixInternalError, errorMsg.c_str()); + hasError = true; } } } @@ -867,7 +899,7 @@ void TDefaultGlslIoResolver::reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& void TDefaultGlslIoResolver::reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) { const TType& type = ent.symbol->getType(); - const TString& name = ent.symbol->getName(); + const TString& name = getAccessName(ent.symbol); int resource = getResourceType(type); if (type.getQualifier().hasBinding()) { TVarSlotMap& varSlotMap = resourceSlotMap[resource]; @@ -884,11 +916,19 @@ void TDefaultGlslIoResolver::reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& if (iter->second != binding) { TString errorMsg = "Invalid binding: " + name; infoSink.info.message(EPrefixInternalError, errorMsg.c_str()); + hasError = true; } } } } +const TString& TDefaultGlslIoResolver::getAccessName(const TIntermSymbol* symbol) +{ + return symbol->getBasicType() == EbtBlock ? + symbol->getType().getTypeName() : + symbol->getName(); +} + //TDefaultGlslIoResolver end /* @@ -1070,11 +1110,12 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TInfoSi TVarGatherTraverser iter_binding_live(intermediate, false, inVarMap, outVarMap, uniformVarMap); root->traverse(&iter_binding_all); iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str()); - while (! iter_binding_live.functions.empty()) { - TIntermNode* function = iter_binding_live.functions.back(); - iter_binding_live.functions.pop_back(); - function->traverse(&iter_binding_live); + while (! iter_binding_live.destinations.empty()) { + TIntermNode* destination = iter_binding_live.destinations.back(); + iter_binding_live.destinations.pop_back(); + destination->traverse(&iter_binding_live); } + // sort entries by priority. see TVarEntryInfo::TOrderByPriority for info. std::for_each(inVarMap.begin(), inVarMap.end(), [&inVector](TVarLivePair p) { inVector.push_back(p); }); @@ -1158,18 +1199,19 @@ bool TGlslIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TIn resolver = &defaultResolver; } resolver->addStage(stage); - inVarMaps[stage] = new TVarLiveMap, outVarMaps[stage] = new TVarLiveMap(), uniformVarMap[stage] = new TVarLiveMap(); + inVarMaps[stage] = new TVarLiveMap(); outVarMaps[stage] = new TVarLiveMap(); uniformVarMap[stage] = new TVarLiveMap(); TVarGatherTraverser iter_binding_all(intermediate, true, *inVarMaps[stage], *outVarMaps[stage], *uniformVarMap[stage]); TVarGatherTraverser iter_binding_live(intermediate, false, *inVarMaps[stage], *outVarMaps[stage], *uniformVarMap[stage]); root->traverse(&iter_binding_all); iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str()); - while (! iter_binding_live.functions.empty()) { - TIntermNode* function = iter_binding_live.functions.back(); - iter_binding_live.functions.pop_back(); - function->traverse(&iter_binding_live); + while (! iter_binding_live.destinations.empty()) { + TIntermNode* destination = iter_binding_live.destinations.back(); + iter_binding_live.destinations.pop_back(); + destination->traverse(&iter_binding_live); } + TNotifyInOutAdaptor inOutNotify(stage, *resolver); TNotifyUniformAdaptor uniformNotify(stage, *resolver); // Resolve current stage input symbol location with previous stage output here, @@ -1246,4 +1288,4 @@ bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) { } // end namespace glslang -#endif // GLSLANG_WEB +#endif // !GLSLANG_WEB && !GLSLANG_ANGLE diff --git a/src/libraries/glslang/glslang/MachineIndependent/iomapper.h b/src/libraries/glslang/glslang/MachineIndependent/iomapper.h index 684e88d57..674132786 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/iomapper.h +++ b/src/libraries/glslang/glslang/MachineIndependent/iomapper.h @@ -33,7 +33,7 @@ // POSSIBILITY OF SUCH DAMAGE. // -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) #ifndef _IOMAPPER_INCLUDED #define _IOMAPPER_INCLUDED @@ -129,6 +129,7 @@ public: uint32_t computeTypeLocationSize(const TType& type, EShLanguage stage); TSlotSetMap slots; + bool hasError = false; protected: TDefaultIoResolverBase(TDefaultIoResolverBase&); @@ -185,7 +186,7 @@ protected: } }; -// Defaulf I/O resolver for OpenGL +// Default I/O resolver for OpenGL struct TDefaultGlslIoResolver : public TDefaultIoResolverBase { public: typedef std::map TVarSlotMap; // @@ -202,6 +203,7 @@ public: void endCollect(EShLanguage) override; void reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) override; void reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) override; + const TString& getAccessName(const TIntermSymbol*); // in/out symbol and uniform symbol are stored in the same resourceSlotMap, the storage key is used to identify each type of symbol. // We use stage and storage qualifier to construct a storage key. it can help us identify the same storage resource used in different stage. // if a resource is a program resource and we don't need know it usage stage, we can use same stage to build storage key. @@ -237,12 +239,13 @@ typedef std::map TVarLiveMap; // In the future, if the vc++ compiler can handle such a situation, // this part of the code will be removed. struct TVarLivePair : std::pair { - TVarLivePair(std::pair& _Right) : pair(_Right.first, _Right.second) {} + TVarLivePair(const std::pair& _Right) : pair(_Right.first, _Right.second) {} TVarLivePair& operator=(const TVarLivePair& _Right) { const_cast(first) = _Right.first; second = _Right.second; return (*this); } + TVarLivePair(const TVarLivePair& src) : pair(src) { } }; typedef std::vector TVarLiveVector; @@ -260,10 +263,10 @@ public: class TGlslIoMapper : public TIoMapper { public: TGlslIoMapper() { - memset(inVarMaps, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1)); - memset(outVarMaps, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1)); - memset(uniformVarMap, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1)); - memset(intermediates, 0, sizeof(TIntermediate*) * (EShLangCount + 1)); + memset(inVarMaps, 0, sizeof(TVarLiveMap*) * EShLangCount); + memset(outVarMaps, 0, sizeof(TVarLiveMap*) * EShLangCount); + memset(uniformVarMap, 0, sizeof(TVarLiveMap*) * EShLangCount); + memset(intermediates, 0, sizeof(TIntermediate*) * EShLangCount); } virtual ~TGlslIoMapper() { for (size_t stage = 0; stage < EShLangCount; stage++) { @@ -296,4 +299,4 @@ public: #endif // _IOMAPPER_INCLUDED -#endif // GLSLANG_WEB +#endif // !GLSLANG_WEB && !GLSLANG_ANGLE diff --git a/src/libraries/glslang/glslang/MachineIndependent/linkValidate.cpp b/src/libraries/glslang/glslang/MachineIndependent/linkValidate.cpp index fe51ec93f..a8e031bc6 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/linkValidate.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/linkValidate.cpp @@ -82,7 +82,7 @@ void TIntermediate::warn(TInfoSink& infoSink, const char* message) // void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit) { -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) mergeCallGraphs(infoSink, unit); mergeModes(infoSink, unit); mergeTrees(infoSink, unit); @@ -104,7 +104,7 @@ void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit) callGraph.insert(callGraph.end(), unit.callGraph.begin(), unit.callGraph.end()); } -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) #define MERGE_MAX(member) member = std::max(member, unit.member) #define MERGE_TRUE(member) if (unit.member) member = unit.member; @@ -138,7 +138,11 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit) MERGE_MAX(spvVersion.openGl); numErrors += unit.getNumErrors(); - numPushConstants += unit.numPushConstants; + // Only one push_constant is allowed, mergeLinkerObjects() will ensure the push_constant + // is the same for all units. + if (numPushConstants > 1 || unit.numPushConstants > 1) + error(infoSink, "Only one push_constant block is allowed per stage"); + numPushConstants = std::min(numPushConstants + unit.numPushConstants, 1); if (unit.invocations != TQualifier::layoutNotSet) { if (invocations == TQualifier::layoutNotSet) @@ -149,7 +153,7 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit) if (vertices == TQualifier::layoutNotSet) vertices = unit.vertices; - else if (vertices != unit.vertices) { + else if (unit.vertices != TQualifier::layoutNotSet && vertices != unit.vertices) { if (language == EShLangGeometry || language == EShLangMeshNV) error(infoSink, "Contradictory layout max_vertices values"); else if (language == EShLangTessControl) @@ -168,12 +172,12 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit) if (inputPrimitive == ElgNone) inputPrimitive = unit.inputPrimitive; - else if (inputPrimitive != unit.inputPrimitive) + else if (unit.inputPrimitive != ElgNone && inputPrimitive != unit.inputPrimitive) error(infoSink, "Contradictory input layout primitives"); if (outputPrimitive == ElgNone) outputPrimitive = unit.outputPrimitive; - else if (outputPrimitive != unit.outputPrimitive) + else if (unit.outputPrimitive != ElgNone && outputPrimitive != unit.outputPrimitive) error(infoSink, "Contradictory output layout primitives"); if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger) @@ -286,7 +290,7 @@ void TIntermediate::mergeTrees(TInfoSink& infoSink, TIntermediate& unit) } // Getting this far means we have two existing trees to merge... - numShaderRecordNVBlocks += unit.numShaderRecordNVBlocks; + numShaderRecordBlocks += unit.numShaderRecordBlocks; numTaskNVBlocks += unit.numTaskNVBlocks; // Get the top-level globals of each unit @@ -299,10 +303,10 @@ void TIntermediate::mergeTrees(TInfoSink& infoSink, TIntermediate& unit) // Map by global name to unique ID to rationalize the same object having // differing IDs in different trees. - TMap idMap; + TIdMaps idMaps; int maxId; - seedIdMap(idMap, maxId); - remapIds(idMap, maxId + 1, unit); + seedIdMap(idMaps, maxId); + remapIds(idMaps, maxId + 1, unit); mergeBodies(infoSink, globals, unitGlobals); mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects); @@ -311,27 +315,40 @@ void TIntermediate::mergeTrees(TInfoSink& infoSink, TIntermediate& unit) #endif +static const TString& getNameForIdMap(TIntermSymbol* symbol) +{ + TShaderInterface si = symbol->getType().getShaderInterface(); + if (si == EsiNone) + return symbol->getName(); + else + return symbol->getType().getTypeName(); +} + + + // Traverser that seeds an ID map with all built-ins, and tracks the // maximum ID used. // (It would be nice to put this in a function, but that causes warnings // on having no bodies for the copy-constructor/operator=.) class TBuiltInIdTraverser : public TIntermTraverser { public: - TBuiltInIdTraverser(TMap& idMap) : idMap(idMap), maxId(0) { } + TBuiltInIdTraverser(TIdMaps& idMaps) : idMaps(idMaps), maxId(0) { } // If it's a built in, add it to the map. // Track the max ID. virtual void visitSymbol(TIntermSymbol* symbol) { const TQualifier& qualifier = symbol->getType().getQualifier(); - if (qualifier.builtIn != EbvNone) - idMap[symbol->getName()] = symbol->getId(); + if (qualifier.builtIn != EbvNone) { + TShaderInterface si = symbol->getType().getShaderInterface(); + idMaps[si][getNameForIdMap(symbol)] = symbol->getId(); + } maxId = std::max(maxId, symbol->getId()); } int getMaxId() const { return maxId; } protected: TBuiltInIdTraverser(TBuiltInIdTraverser&); TBuiltInIdTraverser& operator=(TBuiltInIdTraverser&); - TMap& idMap; + TIdMaps& idMaps; int maxId; }; @@ -340,31 +357,33 @@ protected: // on having no bodies for the copy-constructor/operator=.) class TUserIdTraverser : public TIntermTraverser { public: - TUserIdTraverser(TMap& idMap) : idMap(idMap) { } + TUserIdTraverser(TIdMaps& idMaps) : idMaps(idMaps) { } // If its a non-built-in global, add it to the map. virtual void visitSymbol(TIntermSymbol* symbol) { const TQualifier& qualifier = symbol->getType().getQualifier(); - if (qualifier.builtIn == EbvNone) - idMap[symbol->getName()] = symbol->getId(); + if (qualifier.builtIn == EbvNone) { + TShaderInterface si = symbol->getType().getShaderInterface(); + idMaps[si][getNameForIdMap(symbol)] = symbol->getId(); + } } protected: TUserIdTraverser(TUserIdTraverser&); TUserIdTraverser& operator=(TUserIdTraverser&); - TMap& idMap; // over biggest id + TIdMaps& idMaps; // over biggest id }; // Initialize the the ID map with what we know of 'this' AST. -void TIntermediate::seedIdMap(TMap& idMap, int& maxId) +void TIntermediate::seedIdMap(TIdMaps& idMaps, int& maxId) { // all built-ins everywhere need to align on IDs and contribute to the max ID - TBuiltInIdTraverser builtInIdTraverser(idMap); + TBuiltInIdTraverser builtInIdTraverser(idMaps); treeRoot->traverse(&builtInIdTraverser); maxId = builtInIdTraverser.getMaxId(); // user variables in the linker object list need to align on ids - TUserIdTraverser userIdTraverser(idMap); + TUserIdTraverser userIdTraverser(idMaps); findLinkerObjects()->traverse(&userIdTraverser); } @@ -373,7 +392,7 @@ void TIntermediate::seedIdMap(TMap& idMap, int& maxId) // on having no bodies for the copy-constructor/operator=.) class TRemapIdTraverser : public TIntermTraverser { public: - TRemapIdTraverser(const TMap& idMap, int idShift) : idMap(idMap), idShift(idShift) { } + TRemapIdTraverser(const TIdMaps& idMaps, int idShift) : idMaps(idMaps), idShift(idShift) { } // Do the mapping: // - if the same symbol, adopt the 'this' ID // - otherwise, ensure a unique ID by shifting to a new space @@ -382,8 +401,9 @@ public: const TQualifier& qualifier = symbol->getType().getQualifier(); bool remapped = false; if (qualifier.isLinkable() || qualifier.builtIn != EbvNone) { - auto it = idMap.find(symbol->getName()); - if (it != idMap.end()) { + TShaderInterface si = symbol->getType().getShaderInterface(); + auto it = idMaps[si].find(getNameForIdMap(symbol)); + if (it != idMaps[si].end()) { symbol->changeId(it->second); remapped = true; } @@ -394,14 +414,14 @@ public: protected: TRemapIdTraverser(TRemapIdTraverser&); TRemapIdTraverser& operator=(TRemapIdTraverser&); - const TMap& idMap; + const TIdMaps& idMaps; int idShift; }; -void TIntermediate::remapIds(const TMap& idMap, int idShift, TIntermediate& unit) +void TIntermediate::remapIds(const TIdMaps& idMaps, int idShift, TIntermediate& unit) { // Remap all IDs to either share or be unique, as dictated by the idMap and idShift. - TRemapIdTraverser idTraverser(idMap, idShift); + TRemapIdTraverser idTraverser(idMaps, idShift); unit.getTreeRoot()->traverse(&idTraverser); } @@ -443,7 +463,19 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin TIntermSymbol* symbol = linkerObjects[linkObj]->getAsSymbolNode(); TIntermSymbol* unitSymbol = unitLinkerObjects[unitLinkObj]->getAsSymbolNode(); assert(symbol && unitSymbol); - if (symbol->getName() == unitSymbol->getName()) { + + bool isSameSymbol = false; + // If they are both blocks in the same shader interface, + // match by the block-name, not the identifier name. + if (symbol->getType().getBasicType() == EbtBlock && unitSymbol->getType().getBasicType() == EbtBlock) { + if (symbol->getType().getShaderInterface() == unitSymbol->getType().getShaderInterface()) { + isSameSymbol = symbol->getType().getTypeName() == unitSymbol->getType().getTypeName(); + } + } + else if (symbol->getName() == unitSymbol->getName()) + isSameSymbol = true; + + if (isSameSymbol) { // filter out copy merge = false; @@ -462,6 +494,9 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin // Check for consistent types/qualification/initializers etc. mergeErrorCheck(infoSink, *symbol, *unitSymbol, false); } + // If different symbols, verify they arn't push_constant since there can only be one per stage + else if (symbol->getQualifier().isPushConstant() && unitSymbol->getQualifier().isPushConstant()) + error(infoSink, "Only one push_constant block is allowed per stage"); } if (merge) linkerObjects.push_back(unitLinkerObjects[unitLinkObj]); @@ -498,7 +533,7 @@ void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType) // void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, bool crossStage) { -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) bool writeTypeComparison = false; // Types have to match @@ -520,6 +555,22 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy writeTypeComparison = true; } + // Uniform and buffer blocks must either both have an instance name, or + // must both be anonymous. The names don't need to match though. + if (symbol.getQualifier().isUniformOrBuffer() && + (IsAnonymous(symbol.getName()) != IsAnonymous(unitSymbol.getName()))) { + error(infoSink, "Matched Uniform or Storage blocks must all be anonymous," + " or all be named:"); + writeTypeComparison = true; + } + + if (symbol.getQualifier().storage == unitSymbol.getQualifier().storage && + (IsAnonymous(symbol.getName()) != IsAnonymous(unitSymbol.getName()) || + (!IsAnonymous(symbol.getName()) && symbol.getName() != unitSymbol.getName()))) { + warn(infoSink, "Matched shader interfaces are using different instance names."); + writeTypeComparison = true; + } + // Precision... if (symbol.getQualifier().precision != unitSymbol.getQualifier().precision) { error(infoSink, "Precision qualifiers must match:"); @@ -555,6 +606,7 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy symbol.getQualifier().queuefamilycoherent != unitSymbol.getQualifier().queuefamilycoherent || symbol.getQualifier().workgroupcoherent != unitSymbol.getQualifier().workgroupcoherent || symbol.getQualifier().subgroupcoherent != unitSymbol.getQualifier().subgroupcoherent || + symbol.getQualifier().shadercallcoherent!= unitSymbol.getQualifier().shadercallcoherent || symbol.getQualifier().nonprivate != unitSymbol.getQualifier().nonprivate || symbol.getQualifier().volatil != unitSymbol.getQualifier().volatil || symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict || @@ -589,9 +641,13 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy } } - if (writeTypeComparison) - infoSink.info << " " << symbol.getName() << ": \"" << symbol.getType().getCompleteString() << "\" versus \"" << - unitSymbol.getType().getCompleteString() << "\"\n"; + if (writeTypeComparison) { + infoSink.info << " " << symbol.getName() << ": \"" << symbol.getType().getCompleteString() << "\" versus "; + if (symbol.getName() != unitSymbol.getName()) + infoSink.info << unitSymbol.getName() << ": "; + + infoSink.info << "\"" << unitSymbol.getType().getCompleteString() << "\"\n"; + } #endif } @@ -721,13 +777,13 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) break; case EShLangCompute: break; - case EShLangRayGenNV: - case EShLangIntersectNV: - case EShLangAnyHitNV: - case EShLangClosestHitNV: - case EShLangMissNV: - case EShLangCallableNV: - if (numShaderRecordNVBlocks > 1) + case EShLangRayGen: + case EShLangIntersect: + case EShLangAnyHit: + case EShLangClosestHit: + case EShLangMiss: + case EShLangCallable: + if (numShaderRecordBlocks > 1) error(infoSink, "Only one shaderRecordNV buffer block is allowed per stage"); break; case EShLangMeshNV: @@ -1306,9 +1362,9 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains // that component's size. Aggregate types are flattened down to the component // level to get this sequence of components." - if (type.isArray()) { + if (type.isSizedArray()) { // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness - assert(type.isSizedArray()); + // Unsized array use to xfb should be a compile error. TType elementType(type, 0); return type.getOuterArraySize() * computeTypeXfbSize(elementType, contains64BitType, contains16BitType, contains16BitType); } @@ -1494,7 +1550,9 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, T RoundToPow2(size, alignment); stride = size; // uses full matrix size for stride of an array of matrices (not quite what rule 6/8, but what's expected) // uses the assumption for rule 10 in the comment above - size = stride * type.getOuterArraySize(); + // use one element to represent the last member of SSBO which is unsized array + int arraySize = (type.isUnsizedArray() && (type.getOuterArraySize() == 0)) ? 1 : type.getOuterArraySize(); + size = stride * arraySize; return alignment; } diff --git a/src/libraries/glslang/glslang/MachineIndependent/localintermediate.h b/src/libraries/glslang/glslang/MachineIndependent/localintermediate.h index cb172e5e9..3cdc1f10c 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/localintermediate.h +++ b/src/libraries/glslang/glslang/MachineIndependent/localintermediate.h @@ -162,7 +162,10 @@ struct TXfbBuffer { #endif // Track a set of strings describing how the module was processed. -// Using the form: +// This includes command line options, transforms, etc., ideally inclusive enough +// to reproduce the steps used to transform the input source to the output. +// E.g., see SPIR-V OpModuleProcessed. +// Each "process" or "transform" uses is expressed in the form: // process arg0 arg1 arg2 ... // process arg0 arg1 arg2 ... // where everything is textual, and there can be zero or more arguments @@ -222,6 +225,40 @@ enum ComputeDerivativeMode { LayoutDerivativeGroupLinear, // derivative_group_linearNV }; +class TIdMaps { +public: + TMap& operator[](int i) { return maps[i]; } + const TMap& operator[](int i) const { return maps[i]; } +private: + TMap maps[EsiCount]; +}; + +class TNumericFeatures { +public: + TNumericFeatures() : features(0) { } + TNumericFeatures(const TNumericFeatures&) = delete; + TNumericFeatures& operator=(const TNumericFeatures&) = delete; + typedef enum : unsigned int { + shader_explicit_arithmetic_types = 1 << 0, + shader_explicit_arithmetic_types_int8 = 1 << 1, + shader_explicit_arithmetic_types_int16 = 1 << 2, + shader_explicit_arithmetic_types_int32 = 1 << 3, + shader_explicit_arithmetic_types_int64 = 1 << 4, + shader_explicit_arithmetic_types_float16 = 1 << 5, + shader_explicit_arithmetic_types_float32 = 1 << 6, + shader_explicit_arithmetic_types_float64 = 1 << 7, + shader_implicit_conversions = 1 << 8, + gpu_shader_fp64 = 1 << 9, + gpu_shader_int16 = 1 << 10, + gpu_shader_half_float = 1 << 11, + } feature; + void insert(feature f) { features |= f; } + void erase(feature f) { features &= ~f; } + bool contains(feature f) const { return (features & f) != 0; } +private: + unsigned int features; +}; + // // Set of helper functions to help parse and build the tree. // @@ -229,7 +266,10 @@ class TIntermediate { public: explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) : language(l), - profile(p), version(v), treeRoot(0), +#ifndef GLSLANG_ANGLE + profile(p), version(v), +#endif + treeRoot(0), numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false), invertY(false), useStorageBuffer(false), @@ -244,15 +284,16 @@ public: inputPrimitive(ElgNone), outputPrimitive(ElgNone), pixelCenterInteger(false), originUpperLeft(false), vertexSpacing(EvsNone), vertexOrder(EvoNone), interlockOrdering(EioNone), pointMode(false), earlyFragmentTests(false), - postDepthCoverage(false), depthLayout(EldNone), + postDepthCoverage(false), depthLayout(EldNone), hlslFunctionality1(false), blendEquations(0), xfbMode(false), multiStream(false), layoutOverrideCoverage(false), geoPassthroughEXT(false), - numShaderRecordNVBlocks(0), + numShaderRecordBlocks(0), computeDerivativeMode(LayoutDerivativeNone), primitives(TQualifier::layoutNotSet), numTaskNVBlocks(0), + layoutPrimitiveCulling(false), autoMapBindings(false), autoMapLocations(false), flattenUniformArrays(false), @@ -282,9 +323,20 @@ public: #endif } - void setVersion(int v) { version = v; } + void setVersion(int v) + { +#ifndef GLSLANG_ANGLE + version = v; +#endif + } + void setProfile(EProfile p) + { +#ifndef GLSLANG_ANGLE + profile = p; +#endif + } + int getVersion() const { return version; } - void setProfile(EProfile p) { profile = p; } EProfile getProfile() const { return profile; } void setSpv(const SpvVersion& s) { @@ -332,6 +384,9 @@ public: case EShTargetVulkan_1_1: processes.addProcess("target-env vulkan1.1"); break; + case EShTargetVulkan_1_2: + processes.addProcess("target-env vulkan1.2"); + break; default: processes.addProcess("target-env vulkanUnknown"); break; @@ -377,7 +432,7 @@ public: void setSource(EShSource s) { source = s; } EShSource getSource() const { return source; } #else - void setSource(EShSource s) { assert(s == EShSourceGlsl); } + void setSource(EShSource s) { assert(s == EShSourceGlsl); (void)s; } EShSource getSource() const { return EShSourceGlsl; } #endif @@ -388,15 +443,15 @@ public: TIntermSymbol* addSymbol(const TType&, const TSourceLoc&); TIntermSymbol* addSymbol(const TIntermSymbol&); TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*); - std::tuple addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* node1); + std::tuple addPairConversion(TOperator op, TIntermTyped* node0, TIntermTyped* node1); TIntermTyped* addUniShapeConversion(TOperator, const TType&, TIntermTyped*); TIntermTyped* addConversion(TBasicType convertTo, TIntermTyped* node) const; void addBiShapeConversion(TOperator, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode); TIntermTyped* addShapeConversion(const TType&, TIntermTyped*); - TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc); - TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc); - TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc); - TIntermTyped* addUnaryMath(TOperator, TIntermTyped* child, TSourceLoc); + TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&); + TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&); + TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, const TSourceLoc&); + TIntermTyped* addUnaryMath(TOperator, TIntermTyped* child, const TSourceLoc&); TIntermTyped* addBuiltInFunctionCall(const TSourceLoc& line, TOperator, bool unary, TIntermNode*, const TType& returnType); bool canImplicitlyPromote(TBasicType from, TBasicType to, TOperator op = EOpNull) const; bool isIntegralPromotion(TBasicType from, TBasicType to) const; @@ -410,7 +465,7 @@ public: TIntermAggregate* makeAggregate(TIntermNode* node); TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&); TIntermAggregate* makeAggregate(const TSourceLoc&); - TIntermTyped* setAggregateOperator(TIntermNode*, TOperator, const TType& type, TSourceLoc); + TIntermTyped* setAggregateOperator(TIntermNode*, TOperator, const TType& type, const TSourceLoc&); bool areAllChildConst(TIntermAggregate* aggrNode); TIntermSelection* addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&); TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&); @@ -439,10 +494,11 @@ public: // Low level functions to add nodes (no conversions or other higher level transformations) // If a type is provided, the node's type will be set to it. - TIntermBinary* addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc) const; - TIntermBinary* addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc, const TType&) const; - TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc) const; - TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc, const TType&) const; + TIntermBinary* addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&) const; + TIntermBinary* addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&, + const TType&) const; + TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, const TSourceLoc&) const; + TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, const TSourceLoc&, const TType&) const; // Constant folding (in Constant.cpp) TIntermTyped* fold(TIntermAggregate* aggrNode); @@ -457,11 +513,7 @@ public: void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&); void addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol&); - void setUseStorageBuffer() - { - useStorageBuffer = true; - processes.addProcess("use-storage-buffer"); - } + void setUseStorageBuffer() { useStorageBuffer = true; } bool usingStorageBuffer() const { return useStorageBuffer; } void setDepthReplacing() { depthReplacing = true; } bool isDepthReplacing() const { return depthReplacing; } @@ -500,7 +552,7 @@ public: bool getAutoMapBindings() const { return false; } bool getAutoMapLocations() const { return false; } int getNumPushConstants() const { return 0; } - void addShaderRecordNVCount() { } + void addShaderRecordCount() { } void addTaskNVCount() { } void setUseVulkanMemoryModel() { } bool usingVulkanMemoryModel() const { return false; } @@ -580,7 +632,7 @@ public: processes.addProcess("flatten-uniform-arrays"); } bool getFlattenUniformArrays() const { return flattenUniformArrays; } -#endif +#endif void setNoStorageFormat(bool b) { useUnknownFormat = b; @@ -617,7 +669,7 @@ public: void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; } int getNumPushConstants() const { return numPushConstants; } - void addShaderRecordNVCount() { ++numShaderRecordNVBlocks; } + void addShaderRecordCount() { ++numShaderRecordBlocks; } void addTaskNVCount() { ++numTaskNVBlocks; } bool setInvocations(int i) @@ -720,6 +772,8 @@ public: void setLayoutDerivativeMode(ComputeDerivativeMode mode) { computeDerivativeMode = mode; } bool hasLayoutDerivativeModeNone() const { return computeDerivativeMode != LayoutDerivativeNone; } ComputeDerivativeMode getLayoutDerivativeModeNone() const { return computeDerivativeMode; } + void setLayoutPrimitiveCulling() { layoutPrimitiveCulling = true; } + bool getLayoutPrimitiveCulling() const { return layoutPrimitiveCulling; } bool setPrimitives(int m) { if (primitives != TQualifier::layoutNotSet) @@ -831,22 +885,25 @@ public: bool getArithemeticInt8Enabled() const { return false; } bool getArithemeticInt16Enabled() const { return false; } bool getArithemeticFloat16Enabled() const { return false; } + void updateNumericFeature(TNumericFeatures::feature f, bool on) { } #else bool getArithemeticInt8Enabled() const { - return extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8); + return numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int8); } bool getArithemeticInt16Enabled() const { - return extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || - extensionRequested(E_GL_AMD_gpu_shader_int16) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16); + return numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) || + numericFeatures.contains(TNumericFeatures::gpu_shader_int16) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int16); } bool getArithemeticFloat16Enabled() const { - return extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || - extensionRequested(E_GL_AMD_gpu_shader_half_float) || - extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float16); + return numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) || + numericFeatures.contains(TNumericFeatures::gpu_shader_half_float) || + numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_float16); } + void updateNumericFeature(TNumericFeatures::feature f, bool on) + { on ? numericFeatures.insert(f) : numericFeatures.erase(f); } #endif protected: @@ -856,8 +913,8 @@ protected: void mergeCallGraphs(TInfoSink&, TIntermediate&); void mergeModes(TInfoSink&, TIntermediate&); void mergeTrees(TInfoSink&, TIntermediate&); - void seedIdMap(TMap& idMap, int& maxId); - void remapIds(const TMap& idMap, int idShift, TIntermediate&); + void seedIdMap(TIdMaps& idMaps, int& maxId); + void remapIds(const TIdMaps& idMaps, int idShift, TIntermediate&); void mergeBodies(TInfoSink&, TIntermSequence& globals, const TIntermSequence& unitGlobals); void mergeLinkerObjects(TInfoSink&, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects); void mergeImplicitArraySizes(TType&, const TType&); @@ -878,17 +935,7 @@ protected: bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&); void performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root); bool isConversionAllowed(TOperator op, TIntermTyped* node) const; - std::tuple getConversionDestinatonType(TBasicType type0, TBasicType type1, TOperator op) const; - - // JohnK: I think this function should go away. - // This data structure is just a log to pass on to back ends. - // Versioning and extensions are handled in Version.cpp, with a rich - // set of functions for querying stages, versions, extension enable/disabled, etc. -#ifdef GLSLANG_WEB - bool extensionRequested(const char *extension) const { return false; } -#else - bool extensionRequested(const char *extension) const {return requestedExtensions.find(extension) != requestedExtensions.end();} -#endif + std::tuple getConversionDestinationType(TBasicType type0, TBasicType type1, TOperator op) const; static const char* getResourceName(TResourceType); @@ -898,8 +945,13 @@ protected: typedef std::list TGraph; TGraph callGraph; +#ifdef GLSLANG_ANGLE + const EProfile profile = ECoreProfile; + const int version = 450; +#else EProfile profile; // source profile int version; // source version +#endif SpvVersion spvVersion; TIntermNode* treeRoot; std::set requestedExtensions; // cumulation of all enabled or required extensions; not connected to what subset of the shader used them @@ -942,10 +994,11 @@ protected: bool multiStream; bool layoutOverrideCoverage; bool geoPassthroughEXT; - int numShaderRecordNVBlocks; + int numShaderRecordBlocks; ComputeDerivativeMode computeDerivativeMode; int primitives; int numTaskNVBlocks; + bool layoutPrimitiveCulling; // Base shift values std::array shiftBinding; @@ -972,6 +1025,7 @@ protected: std::unordered_map uniformLocationOverrides; int uniformLocationBase; + TNumericFeatures numericFeatures; #endif std::unordered_set usedConstantId; // specialization constant ids used diff --git a/src/libraries/glslang/glslang/MachineIndependent/parseConst.cpp b/src/libraries/glslang/glslang/MachineIndependent/parseConst.cpp index 1a8e6d998..7c04743ba 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/parseConst.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/parseConst.cpp @@ -165,17 +165,27 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node) } } } else { - // matrix from vector + // matrix from vector or scalar int count = 0; const int startIndex = index; int nodeComps = node->getType().computeNumComponents(); for (int i = startIndex; i < endIndex; i++) { if (i >= instanceSize) return; - if (i == startIndex || (i - startIndex) % (matrixRows + 1) == 0 ) + if (nodeComps == 1) { + // If there is a single scalar parameter to a matrix + // constructor, it is used to initialize all the + // components on the matrix's diagonal, with the + // remaining components initialized to 0.0. + if (i == startIndex || (i - startIndex) % (matrixRows + 1) == 0 ) + leftUnionArray[i] = rightUnionArray[count]; + else + leftUnionArray[i].setDConst(0.0); + } else { + // construct the matrix in column-major order, from + // the components provided, in order leftUnionArray[i] = rightUnionArray[count]; - else - leftUnionArray[i].setDConst(0.0); + } index++; diff --git a/src/libraries/glslang/glslang/MachineIndependent/parseVersions.h b/src/libraries/glslang/glslang/MachineIndependent/parseVersions.h index aa1964fc2..7248354e4 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/parseVersions.h +++ b/src/libraries/glslang/glslang/MachineIndependent/parseVersions.h @@ -58,7 +58,7 @@ public: const SpvVersion& spvVersion, EShLanguage language, TInfoSink& infoSink, bool forwardCompatible, EShMessages messages) : -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) forwardCompatible(forwardCompatible), profile(profile), #endif @@ -101,6 +101,7 @@ public: void updateExtensionBehavior(int line, const char* const extension, const char* behavior) { } void updateExtensionBehavior(const char* const extension, TExtensionBehavior) { } void checkExtensionStage(const TSourceLoc&, const char* const extension) { } + void extensionRequires(const TSourceLoc&, const char* const extension, const char* behavior) { } void fullIntegerCheck(const TSourceLoc&, const char* op) { } void doubleCheck(const TSourceLoc&, const char* op) { } bool float16Arithmetic() { return false; } @@ -115,9 +116,14 @@ public: bool relaxedErrors() const { return false; } bool suppressWarnings() const { return true; } bool isForwardCompatible() const { return false; } +#else +#ifdef GLSLANG_ANGLE + const bool forwardCompatible = true; + const EProfile profile = ECoreProfile; #else bool forwardCompatible; // true if errors are to be given for use of deprecated features EProfile profile; // the declared profile in the shader (core by default) +#endif bool isEsProfile() const { return profile == EEsProfile; } void requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc); void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions, @@ -139,6 +145,7 @@ public: virtual bool checkExtensionsRequested(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc); virtual void checkExtensionStage(const TSourceLoc&, const char* const extension); + virtual void extensionRequires(const TSourceLoc&, const char* const extension, const char* behavior); virtual void fullIntegerCheck(const TSourceLoc&, const char* op); virtual void unimplemented(const TSourceLoc&, const char* featureDesc); @@ -170,6 +177,7 @@ public: virtual void vulkanRemoved(const TSourceLoc&, const char* op); virtual void requireVulkan(const TSourceLoc&, const char* op); virtual void requireSpv(const TSourceLoc&, const char* op); + virtual void requireSpv(const TSourceLoc&, const char *op, unsigned int version); #if defined(GLSLANG_WEB) && !defined(GLSLANG_WEB_DEVEL) @@ -221,7 +229,8 @@ public: TIntermediate& intermediate; // helper for making and hooking up pieces of the parse tree protected: - TMap extensionBehavior; // for each extension string, what its current behavior is set to + TMap extensionBehavior; // for each extension string, what its current behavior is + TMap extensionMinSpv; // for each extension string, store minimum spirv required EShMessages messages; // errors/warnings/rule-sets int numErrors; // number of compile-time errors encountered TInputScanner* currentScanner; diff --git a/src/libraries/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp b/src/libraries/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp index d7ff485c0..a0a626f9b 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp @@ -422,10 +422,10 @@ int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, boo if (! parseContext.isReadingHLSL() && isMacroInput()) { if (parseContext.relaxedErrors()) parseContext.ppWarn(ppToken->loc, "nonportable when expanded from macros for preprocessor expression", - "defined", ""); + "defined", ""); else parseContext.ppError(ppToken->loc, "cannot use in preprocessor expression when expanded from macros", - "defined", ""); + "defined", ""); } bool needclose = 0; token = scanToken(ppToken); @@ -621,14 +621,25 @@ int TPpContext::CPPinclude(TPpToken* ppToken) { const TSourceLoc directiveLoc = ppToken->loc; bool startWithLocalSearch = true; // to additionally include the extra "" paths - int token = scanToken(ppToken); + int token; - // handle -style #include - if (token == '<') { + // Find the first non-whitespace char after #include + int ch = getChar(); + while (ch == ' ' || ch == '\t') { + ch = getChar(); + } + if (ch == '<') { + // style startWithLocalSearch = false; token = scanHeaderName(ppToken, '>'); + } else if (ch == '"') { + // "header-name" style + token = scanHeaderName(ppToken, '"'); + } else { + // unexpected, get the full token to generate the error + ungetChar(); + token = scanToken(ppToken); } - // otherwise ppToken already has the header name and it was "header-name" style if (token != PpAtomConstString) { parseContext.ppError(directiveLoc, "must be followed by a header name", "#include", ""); @@ -711,7 +722,9 @@ int TPpContext::CPPline(TPpToken* ppToken) const char* sourceName = nullptr; // Optional source file name. bool lineErr = false; bool fileErr = false; + disableEscapeSequences = true; token = eval(token, MIN_PRECEDENCE, false, lineRes, lineErr, ppToken); + disableEscapeSequences = false; if (! lineErr) { lineToken = lineRes; if (token == '\n') @@ -754,7 +767,9 @@ int TPpContext::CPPline(TPpToken* ppToken) // Handle #error int TPpContext::CPPerror(TPpToken* ppToken) { + disableEscapeSequences = true; int token = scanToken(ppToken); + disableEscapeSequences = false; std::string message; TSourceLoc loc = ppToken->loc; @@ -1169,7 +1184,9 @@ MacroExpandResult TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, b int macroAtom = atomStrings.getAtom(ppToken->name); switch (macroAtom) { case PpAtomLineMacro: - ppToken->ival = parseContext.getCurrentLoc().line; + // Arguments which are macro have been replaced in the first stage. + if (ppToken->ival == 0) + ppToken->ival = parseContext.getCurrentLoc().line; snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival); UngetToken(PpAtomConstInt, ppToken); return MacroExpandStarted; @@ -1270,6 +1287,11 @@ MacroExpandResult TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, b nestStack.push_back('}'); else if (nestStack.size() > 0 && token == nestStack.back()) nestStack.pop_back(); + + //Macro replacement list is expanded in the last stage. + if (atomStrings.getAtom(ppToken->name) == PpAtomLineMacro) + ppToken->ival = parseContext.getCurrentLoc().line; + in->args[arg]->putToken(token, ppToken); tokenRecorded = true; } diff --git a/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp b/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp index cc003a8d1..1363ce2be 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp @@ -87,7 +87,8 @@ namespace glslang { TPpContext::TPpContext(TParseContextBase& pc, const std::string& rootFileName, TShader::Includer& inclr) : preamble(0), strings(0), previous_token('\n'), parseContext(pc), includer(inclr), inComment(false), rootFileName(rootFileName), - currentSourceFile(rootFileName) + currentSourceFile(rootFileName), + disableEscapeSequences(false) { ifdepth = 0; for (elsetracker = 0; elsetracker < maxIfNesting; elsetracker++) diff --git a/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.h b/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.h index 8470e172a..714b5eadb 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.h +++ b/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.h @@ -105,13 +105,13 @@ public: } // Used for comparing macro definitions, so checks what is relevant for that. - bool operator==(const TPpToken& right) + bool operator==(const TPpToken& right) const { return space == right.space && ival == right.ival && dval == right.dval && i64val == right.i64val && strncmp(name, right.name, MaxTokenLength) == 0; } - bool operator!=(const TPpToken& right) { return ! operator==(right); } + bool operator!=(const TPpToken& right) const { return ! operator==(right); } TSourceLoc loc; // True if a space (for white space or a removed comment) should also be @@ -695,6 +695,7 @@ protected: std::string currentSourceFile; std::istringstream strtodStream; + bool disableEscapeSequences; }; } // end namespace glslang diff --git a/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp b/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp index c293af3c1..e0f44f8b4 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp @@ -1026,12 +1026,80 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) case '\'': return pp->characterLiteral(ppToken); case '"': - // TODO: If this gets enhanced to handle escape sequences, or - // anything that is different than what #include needs, then - // #include needs to use scanHeaderName() for this. + // #include uses scanHeaderName() to ignore these escape sequences. ch = getch(); while (ch != '"' && ch != '\n' && ch != EndOfInput) { if (len < MaxTokenLength) { + if (ch == '\\' && !pp->disableEscapeSequences) { + int nextCh = getch(); + switch (nextCh) { + case '\'': ch = 0x27; break; + case '"': ch = 0x22; break; + case '?': ch = 0x3f; break; + case '\\': ch = 0x5c; break; + case 'a': ch = 0x07; break; + case 'b': ch = 0x08; break; + case 'f': ch = 0x0c; break; + case 'n': ch = 0x0a; break; + case 'r': ch = 0x0d; break; + case 't': ch = 0x09; break; + case 'v': ch = 0x0b; break; + case 'x': + // Hex value, arbitrary number of characters. Terminated by the first + // non-hex digit + { + int numDigits = 0; + ch = 0; + while (true) { + nextCh = getch(); + if (nextCh >= '0' && nextCh <= '9') + nextCh -= '0'; + else if (nextCh >= 'A' && nextCh <= 'F') + nextCh -= 'A' - 10; + else if (nextCh >= 'a' && nextCh <= 'f') + nextCh -= 'a' - 10; + else { + ungetch(); + break; + } + numDigits++; + ch = ch * 0x10 + nextCh; + } + if (numDigits == 0) { + pp->parseContext.ppError(ppToken->loc, "Expected hex value in escape sequence", "string", ""); + } + break; + } + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + // Octal value, up to three octal digits + { + int numDigits = 1; + ch = nextCh - '0'; + while (numDigits < 3) { + nextCh = getch(); + if (nextCh >= '0' && nextCh <= '7') + nextCh -= '0'; + else { + ungetch(); + break; + } + numDigits++; + ch = ch * 8 + nextCh; + } + break; + } + default: + pp->parseContext.ppError(ppToken->loc, "Invalid escape sequence", "string", ""); + break; + } + } ppToken->name[len] = (char)ch; len++; ch = getch(); @@ -1120,10 +1188,12 @@ int TPpContext::tokenize(TPpToken& ppToken) continue; break; case PpAtomConstString: + // HLSL allows string literals. + // GLSL allows string literals with GL_EXT_debug_printf. if (ifdepth == 0 && parseContext.intermediate.getSource() != EShSourceHlsl) { - // HLSL allows string literals. - parseContext.ppError(ppToken.loc, "string literals not supported", "\"\"", ""); - continue; + parseContext.requireExtensions(ppToken.loc, 1, &E_GL_EXT_debug_printf, "string literal"); + if (!parseContext.extensionTurnedOn(E_GL_EXT_debug_printf)) + continue; } break; case '\'': diff --git a/src/libraries/glslang/glslang/MachineIndependent/propagateNoContraction.cpp b/src/libraries/glslang/glslang/MachineIndependent/propagateNoContraction.cpp index 83a3230f5..9def592ba 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/propagateNoContraction.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/propagateNoContraction.cpp @@ -867,4 +867,4 @@ void PropagateNoContraction(const glslang::TIntermediate& intermediate) } }; -#endif // GLSLANG_WEB \ No newline at end of file +#endif // GLSLANG_WEB diff --git a/src/libraries/glslang/glslang/MachineIndependent/reflection.cpp b/src/libraries/glslang/glslang/MachineIndependent/reflection.cpp index b09367113..0aabf37fb 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/reflection.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/reflection.cpp @@ -33,7 +33,7 @@ // POSSIBILITY OF SUCH DAMAGE. // -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) #include "../Include/Common.h" #include "reflection.h" @@ -77,10 +77,10 @@ namespace glslang { // This is in the glslang namespace directly so it can be a friend of TReflection. // -class TReflectionTraverser : public TLiveTraverser { +class TReflectionTraverser : public TIntermTraverser { public: TReflectionTraverser(const TIntermediate& i, TReflection& r) : - TLiveTraverser(i), reflection(r) { } + TIntermTraverser(), intermediate(i), reflection(r), updateStageMasks(true) { } virtual bool visitBinary(TVisit, TIntermBinary* node); virtual void visitSymbol(TIntermSymbol* base); @@ -92,11 +92,28 @@ public: if (processedDerefs.find(&base) == processedDerefs.end()) { processedDerefs.insert(&base); + int blockIndex = -1; + int offset = -1; + TList derefs; + TString baseName = base.getName(); + + if (base.getType().getBasicType() == EbtBlock) { + offset = 0; + bool anonymous = IsAnonymous(baseName); + const TString& blockName = base.getType().getTypeName(); + + if (!anonymous) + baseName = blockName; + else + baseName = ""; + + blockIndex = addBlockName(blockName, base.getType(), intermediate.getBlockSize(base.getType())); + } + // Use a degenerate (empty) set of dereferences to immediately put as at the end of // the dereference change expected by blowUpActiveAggregate. - TList derefs; - blowUpActiveAggregate(base.getType(), base.getName(), derefs, derefs.end(), -1, -1, 0, 0, - base.getQualifier().storage, true); + blowUpActiveAggregate(base.getType(), baseName, derefs, derefs.end(), offset, blockIndex, 0, -1, 0, + base.getQualifier().storage, updateStageMasks); } } @@ -155,9 +172,9 @@ public: void getOffsets(const TType& type, TVector& offsets) { const TTypeList& memberList = *type.getStruct(); - int memberSize = 0; int offset = 0; + for (size_t m = 0; m < offsets.size(); ++m) { // if the user supplied an offset, snap to it now if (memberList[m].type->getQualifier().hasOffset()) @@ -233,7 +250,7 @@ public: // A value of 0 for arraySize will mean to use the full array's size. void blowUpActiveAggregate(const TType& baseType, const TString& baseName, const TList& derefs, TList::const_iterator deref, int offset, int blockIndex, int arraySize, - int topLevelArrayStride, TStorageQualifier baseStorage, bool active) + int topLevelArraySize, int topLevelArrayStride, TStorageQualifier baseStorage, bool active) { // when strictArraySuffix is enabled, we closely follow the rules from ARB_program_interface_query. // Broadly: @@ -262,14 +279,15 @@ public: // Visit all the indices of this array, and for each one add on the remaining dereferencing for (int i = 0; i < std::max(visitNode->getLeft()->getType().getOuterArraySize(), 1); ++i) { TString newBaseName = name; - if (strictArraySuffix && blockParent) + if (terminalType->getBasicType() == EbtBlock) {} + else if (strictArraySuffix && blockParent) newBaseName.append(TString("[0]")); else if (strictArraySuffix || baseType.getBasicType() != EbtBlock) newBaseName.append(TString("[") + String(i) + "]"); TList::const_iterator nextDeref = deref; ++nextDeref; blowUpActiveAggregate(*terminalType, newBaseName, derefs, nextDeref, offset, blockIndex, arraySize, - topLevelArrayStride, baseStorage, active); + topLevelArraySize, topLevelArrayStride, baseStorage, active); if (offset >= 0) offset += stride; @@ -282,9 +300,10 @@ public: int stride = getArrayStride(baseType, visitNode->getLeft()->getType()); index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst(); - if (strictArraySuffix && blockParent) { + if (terminalType->getBasicType() == EbtBlock) {} + else if (strictArraySuffix && blockParent) name.append(TString("[0]")); - } else if (strictArraySuffix || baseType.getBasicType() != EbtBlock) { + else if (strictArraySuffix || baseType.getBasicType() != EbtBlock) { name.append(TString("[") + String(index) + "]"); if (offset >= 0) @@ -294,7 +313,10 @@ public: if (topLevelArrayStride == 0) topLevelArrayStride = stride; - blockParent = false; + // expand top-level arrays in blocks with [0] suffix + if (topLevelArrayStride != 0 && visitNode->getLeft()->getType().isArray()) { + blockParent = false; + } break; } case EOpIndexDirectStruct: @@ -304,6 +326,12 @@ public: if (name.size() > 0) name.append("."); name.append((*visitNode->getLeft()->getType().getStruct())[index].type->getFieldName()); + + // expand non top-level arrays with [x] suffix + if (visitNode->getLeft()->getType().getBasicType() != EbtBlock && terminalType->isArray()) + { + blockParent = false; + } break; default: break; @@ -323,24 +351,27 @@ public: if (offset >= 0) stride = getArrayStride(baseType, *terminalType); - if (topLevelArrayStride == 0) - topLevelArrayStride = stride; - int arrayIterateSize = std::max(terminalType->getOuterArraySize(), 1); // for top-level arrays in blocks, only expand [0] to avoid explosion of items - if (strictArraySuffix && blockParent) + if ((strictArraySuffix && blockParent) || + ((topLevelArraySize == arrayIterateSize) && (topLevelArrayStride == 0))) { arrayIterateSize = 1; + } + + if (topLevelArrayStride == 0) + topLevelArrayStride = stride; for (int i = 0; i < arrayIterateSize; ++i) { TString newBaseName = name; - newBaseName.append(TString("[") + String(i) + "]"); + if (terminalType->getBasicType() != EbtBlock) + newBaseName.append(TString("[") + String(i) + "]"); TType derefType(*terminalType, 0); if (offset >= 0) offset = baseOffset + stride * i; blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0, - topLevelArrayStride, baseStorage, active); + topLevelArraySize, topLevelArrayStride, baseStorage, active); } } else { // Visit all members of this aggregate, and for each one, @@ -369,8 +400,31 @@ public: arrayStride = getArrayStride(baseType, derefType); } - blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0, - arrayStride, baseStorage, active); + if (topLevelArraySize == -1 && arrayStride == 0 && blockParent) + topLevelArraySize = 1; + + if (strictArraySuffix && blockParent) { + // if this member is an array, store the top-level array stride but start the explosion from + // the inner struct type. + if (derefType.isArray() && derefType.isStruct()) { + newBaseName.append("[0]"); + auto dimSize = derefType.isUnsizedArray() ? 0 : derefType.getArraySizes()->getDimSize(0); + blowUpActiveAggregate(TType(derefType, 0), newBaseName, derefs, derefs.end(), memberOffsets[i], + blockIndex, 0, dimSize, arrayStride, terminalType->getQualifier().storage, false); + } + else if (derefType.isArray()) { + auto dimSize = derefType.isUnsizedArray() ? 0 : derefType.getArraySizes()->getDimSize(0); + blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), memberOffsets[i], blockIndex, + 0, dimSize, 0, terminalType->getQualifier().storage, false); + } + else { + blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), memberOffsets[i], blockIndex, + 0, 1, 0, terminalType->getQualifier().storage, false); + } + } else { + blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0, + topLevelArraySize, arrayStride, baseStorage, active); + } } } @@ -406,6 +460,7 @@ public: if ((reflection.options & EShReflectionSeparateBuffers) && terminalType->isAtomic()) reflection.atomicCounterUniformIndices.push_back(uniformIndex); + variables.back().topLevelArraySize = topLevelArraySize; variables.back().topLevelArrayStride = topLevelArrayStride; if ((reflection.options & EShReflectionAllBlockVariables) && active) { @@ -537,65 +592,17 @@ public: if (! anonymous) baseName = blockName; - if (base->getType().isArray()) { - TType derefType(base->getType(), 0); - - assert(! anonymous); - for (int e = 0; e < base->getType().getCumulativeArraySize(); ++e) - blockIndex = addBlockName(blockName + "[" + String(e) + "]", derefType, - intermediate.getBlockSize(base->getType())); - baseName.append(TString("[0]")); - } else - blockIndex = addBlockName(blockName, base->getType(), intermediate.getBlockSize(base->getType())); + blockIndex = addBlockName(blockName, base->getType(), intermediate.getBlockSize(base->getType())); if (reflection.options & EShReflectionAllBlockVariables) { // Use a degenerate (empty) set of dereferences to immediately put as at the end of // the dereference change expected by blowUpActiveAggregate. TList derefs; - // because we don't have any derefs, the first thing blowUpActiveAggregate will do is iterate over each - // member in the struct definition. This will lose any information about whether the parent was a buffer - // block. So if we're using strict array rules which don't expand the first child of a buffer block we - // instead iterate over the children here. - const bool strictArraySuffix = (reflection.options & EShReflectionStrictArraySuffix); - bool blockParent = (base->getType().getBasicType() == EbtBlock && base->getQualifier().storage == EvqBuffer); - - if (strictArraySuffix && blockParent) { - TType structDerefType(base->getType(), 0); - - const TType &structType = base->getType().isArray() ? structDerefType : base->getType(); - const TTypeList& typeList = *structType.getStruct(); - - TVector memberOffsets; - - memberOffsets.resize(typeList.size()); - getOffsets(structType, memberOffsets); - - for (int i = 0; i < (int)typeList.size(); ++i) { - TType derefType(structType, i); - TString name = baseName; - if (name.size() > 0) - name.append("."); - name.append(typeList[i].type->getFieldName()); - - // if this member is an array, store the top-level array stride but start the explosion from - // the inner struct type. - if (derefType.isArray() && derefType.isStruct()) { - name.append("[0]"); - blowUpActiveAggregate(TType(derefType, 0), name, derefs, derefs.end(), memberOffsets[i], - blockIndex, 0, getArrayStride(structType, derefType), - base->getQualifier().storage, false); - } else { - blowUpActiveAggregate(derefType, name, derefs, derefs.end(), memberOffsets[i], blockIndex, - 0, 0, base->getQualifier().storage, false); - } - } - } else { - // otherwise - if we're not using strict array suffix rules, or this isn't a block so we are - // expanding root arrays anyway, just start the iteration from the base block type. - blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.end(), 0, blockIndex, 0, 0, + // otherwise - if we're not using strict array suffix rules, or this isn't a block so we are + // expanding root arrays anyway, just start the iteration from the base block type. + blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.end(), 0, blockIndex, 0, -1, 0, base->getQualifier().storage, false); - } } } @@ -626,30 +633,40 @@ public: else baseName = base->getName(); } - blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.begin(), offset, blockIndex, arraySize, 0, + blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.begin(), offset, blockIndex, arraySize, -1, 0, base->getQualifier().storage, true); } int addBlockName(const TString& name, const TType& type, int size) { - TReflection::TMapIndexToReflection& blocks = reflection.GetBlockMapForStorage(type.getQualifier().storage); - - int blockIndex; - TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str()); - if (reflection.nameToIndex.find(name.c_str()) == reflection.nameToIndex.end()) { - blockIndex = (int)blocks.size(); - reflection.nameToIndex[name.c_str()] = blockIndex; - blocks.push_back(TObjectReflection(name.c_str(), type, -1, -1, size, -1)); - - blocks.back().numMembers = countAggregateMembers(type); - - EShLanguageMask& stages = blocks.back().stages; - stages = static_cast(stages | 1 << intermediate.getStage()); + int blockIndex = 0; + if (type.isArray()) { + TType derefType(type, 0); + for (int e = 0; e < type.getOuterArraySize(); ++e) { + int memberBlockIndex = addBlockName(name + "[" + String(e) + "]", derefType, size); + if (e == 0) + blockIndex = memberBlockIndex; + } } else { - blockIndex = it->second; + TReflection::TMapIndexToReflection& blocks = reflection.GetBlockMapForStorage(type.getQualifier().storage); - EShLanguageMask& stages = blocks[blockIndex].stages; - stages = static_cast(stages | 1 << intermediate.getStage()); + TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str()); + if (reflection.nameToIndex.find(name.c_str()) == reflection.nameToIndex.end()) { + blockIndex = (int)blocks.size(); + reflection.nameToIndex[name.c_str()] = blockIndex; + blocks.push_back(TObjectReflection(name.c_str(), type, -1, -1, size, blockIndex)); + + blocks.back().numMembers = countAggregateMembers(type); + + EShLanguageMask& stages = blocks.back().stages; + stages = static_cast(stages | 1 << intermediate.getStage()); + } + else { + blockIndex = it->second; + + EShLanguageMask& stages = blocks[blockIndex].stages; + stages = static_cast(stages | 1 << intermediate.getStage()); + } } return blockIndex; @@ -995,8 +1012,10 @@ public: return type.isArray() ? type.getOuterArraySize() : 1; } + const TIntermediate& intermediate; TReflection& reflection; std::set processedDerefs; + bool updateStageMasks; protected: TReflectionTraverser(TReflectionTraverser&); @@ -1029,7 +1048,21 @@ bool TReflectionTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node) // To reflect non-dereferenced objects. void TReflectionTraverser::visitSymbol(TIntermSymbol* base) { - if (base->getQualifier().storage == EvqUniform) + if (base->getQualifier().storage == EvqUniform) { + if (base->getBasicType() == EbtBlock) { + if (reflection.options & EShReflectionSharedStd140UBO) { + addUniform(*base); + } + } else { + addUniform(*base); + } + } + + // #TODO add std140/layout active rules for ssbo, same with ubo. + // Storage buffer blocks will be collected and expanding in this part. + if((reflection.options & EShReflectionSharedStd140SSBO) && + (base->getQualifier().storage == EvqBuffer && base->getBasicType() == EbtBlock && + (base->getQualifier().layoutPacking == ElpStd140 || base->getQualifier().layoutPacking == ElpShared))) addUniform(*base); if ((intermediate.getStage() == reflection.firstStage && base->getQualifier().isPipeInput()) || @@ -1135,15 +1168,47 @@ bool TReflection::addStage(EShLanguage stage, const TIntermediate& intermediate) TReflectionTraverser it(intermediate, *this); - // put the entry point on the list of functions to process - it.pushFunction(intermediate.getEntryPointMangledName().c_str()); - - // process all the functions - while (! it.functions.empty()) { - TIntermNode* function = it.functions.back(); - it.functions.pop_back(); - function->traverse(&it); + for (auto& sequnence : intermediate.getTreeRoot()->getAsAggregate()->getSequence()) { + if (sequnence->getAsAggregate() != nullptr) { + if (sequnence->getAsAggregate()->getOp() == glslang::EOpLinkerObjects) { + it.updateStageMasks = false; + TIntermAggregate* linkerObjects = sequnence->getAsAggregate(); + for (auto& sequnence : linkerObjects->getSequence()) { + auto pNode = sequnence->getAsSymbolNode(); + if (pNode != nullptr) { + if ((pNode->getQualifier().storage == EvqUniform && + (options & EShReflectionSharedStd140UBO)) || + (pNode->getQualifier().storage == EvqBuffer && + (options & EShReflectionSharedStd140SSBO))) { + // collect std140 and shared uniform block form AST + if ((pNode->getBasicType() == EbtBlock) && + ((pNode->getQualifier().layoutPacking == ElpStd140) || + (pNode->getQualifier().layoutPacking == ElpShared))) { + pNode->traverse(&it); + } + } + else if ((options & EShReflectionAllIOVariables) && + (pNode->getQualifier().isPipeInput() || pNode->getQualifier().isPipeOutput())) + { + pNode->traverse(&it); + } + } + } + } else { + // This traverser will travers all function in AST. + // If we want reflect uncalled function, we need set linke message EShMsgKeepUncalled. + // When EShMsgKeepUncalled been set to true, all function will be keep in AST, even it is a uncalled function. + // This will keep some uniform variables in reflection, if those uniform variables is used in these uncalled function. + // + // If we just want reflect only live node, we can use a default link message or set EShMsgKeepUncalled false. + // When linke message not been set EShMsgKeepUncalled, linker won't keep uncalled function in AST. + // So, travers all function node can equivalent to travers live function. + it.updateStageMasks = true; + sequnence->getAsAggregate()->traverse(&it); + } + } } + it.updateStageMasks = true; buildCounterIndices(intermediate); buildUniformStageMask(intermediate); @@ -1188,7 +1253,7 @@ void TReflection::dump() for (int dim=0; dim<3; ++dim) if (getLocalSize(dim) > 1) - printf("Local size %s: %d\n", axis[dim], getLocalSize(dim)); + printf("Local size %s: %u\n", axis[dim], getLocalSize(dim)); printf("\n"); } @@ -1201,4 +1266,4 @@ void TReflection::dump() } // end namespace glslang -#endif // GLSLANG_WEB +#endif // !GLSLANG_WEB && !GLSLANG_ANGLE diff --git a/src/libraries/glslang/glslang/MachineIndependent/reflection.h b/src/libraries/glslang/glslang/MachineIndependent/reflection.h index efdc8934f..5af4467c1 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/reflection.h +++ b/src/libraries/glslang/glslang/MachineIndependent/reflection.h @@ -33,7 +33,7 @@ // POSSIBILITY OF SUCH DAMAGE. // -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) #ifndef _REFLECTION_INCLUDED #define _REFLECTION_INCLUDED @@ -220,4 +220,4 @@ protected: #endif // _REFLECTION_INCLUDED -#endif // GLSLANG_WEB \ No newline at end of file +#endif // !GLSLANG_WEB && !GLSLANG_ANGLE diff --git a/src/libraries/glslang/glslang/OSDependent/Web/glslang.js.cpp b/src/libraries/glslang/glslang/OSDependent/Web/glslang.js.cpp index 6cb93fe27..f2306a609 100644 --- a/src/libraries/glslang/glslang/OSDependent/Web/glslang.js.cpp +++ b/src/libraries/glslang/glslang/OSDependent/Web/glslang.js.cpp @@ -141,6 +141,7 @@ const TBuiltInResource DefaultTBuiltInResource = { /* .maxTaskWorkGroupSizeY_NV = */ 1, /* .maxTaskWorkGroupSizeZ_NV = */ 1, /* .maxMeshViewCountNV = */ 4, + /* .maxDualSourceDrawBuffersEXT = */ 1, /* .limits = */ { /* .nonInductiveForLoops = */ 1, @@ -176,7 +177,12 @@ extern "C" { * If null, the compilation failed. */ EMSCRIPTEN_KEEPALIVE -void* convert_glsl_to_spirv(const char* glsl, int stage_int, bool gen_debug, uint32_t** spirv, size_t* spirv_len) +void* convert_glsl_to_spirv(const char* glsl, + int stage_int, + bool gen_debug, + glslang::EShTargetLanguageVersion spirv_version, + uint32_t** spirv, + size_t* spirv_len) { if (glsl == nullptr) { fprintf(stderr, "Input pointer null\n"); @@ -194,6 +200,18 @@ void* convert_glsl_to_spirv(const char* glsl, int stage_int, bool gen_debug, uin return nullptr; } EShLanguage stage = static_cast(stage_int); + switch (spirv_version) { + case glslang::EShTargetSpv_1_0: + case glslang::EShTargetSpv_1_1: + case glslang::EShTargetSpv_1_2: + case glslang::EShTargetSpv_1_3: + case glslang::EShTargetSpv_1_4: + case glslang::EShTargetSpv_1_5: + break; + default: + fprintf(stderr, "Invalid SPIR-V version number\n"); + return nullptr; + } if (!initialized) { glslang::InitializeProcess(); @@ -203,8 +221,8 @@ void* convert_glsl_to_spirv(const char* glsl, int stage_int, bool gen_debug, uin glslang::TShader shader(stage); shader.setStrings(&glsl, 1); shader.setEnvInput(glslang::EShSourceGlsl, stage, glslang::EShClientVulkan, 100); - shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_1); - shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_3); + shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_0); + shader.setEnvTarget(glslang::EShTargetSpv, spirv_version); if (!shader.parse(&DefaultTBuiltInResource, 100, true, EShMsgDefault)) { fprintf(stderr, "Parse failed\n"); fprintf(stderr, "%s\n", shader.getInfoLog()); @@ -260,7 +278,7 @@ void main() { })"; uint32_t* output; size_t output_len; - void* id = convert_glsl_to_spirv(input, 4, false, &output, &output_len); + void* id = convert_glsl_to_spirv(input, 4, false, glslang::EShTargetSpv_1_0, &output, &output_len); assert(output != nullptr); assert(output_len != 0); destroy_output_buffer(id); diff --git a/src/libraries/glslang/glslang/OSDependent/Web/glslang.pre.js b/src/libraries/glslang/glslang/OSDependent/Web/glslang.pre.js index 7d3fd0234..46a569506 100644 --- a/src/libraries/glslang/glslang/OSDependent/Web/glslang.pre.js +++ b/src/libraries/glslang/glslang/OSDependent/Web/glslang.pre.js @@ -1,23 +1,34 @@ -Module['compileGLSLZeroCopy'] = function(glsl, shader_stage, gen_debug) { +Module['compileGLSLZeroCopy'] = function(glsl, shader_stage, gen_debug, spirv_version) { gen_debug = !!gen_debug; - var shader_stage_int; - if (shader_stage === 'vertex') { - shader_stage_int = 0; - } else if (shader_stage === 'fragment') { - shader_stage_int = 4; - } else if (shader_stage === 'compute') { - shader_stage_int = 5; - } else { - throw new Error("shader_stage must be 'vertex', 'fragment', or 'compute'"); + var shader_stage_int; // EShLanguage + switch (shader_stage) { + case 'vertex': shader_stage_int = 0; break; + case 'fragment': shader_stage_int = 4; break; + case 'compute': shader_stage_int = 5; break; + default: + throw new Error("shader_stage must be 'vertex', 'fragment', or 'compute'."); + } + + spirv_version = spirv_version || '1.0'; + var spirv_version_int; // EShTargetLanguageVersion + switch (spirv_version) { + case '1.0': spirv_version_int = (1 << 16) | (0 << 8); break; + case '1.1': spirv_version_int = (1 << 16) | (1 << 8); break; + case '1.2': spirv_version_int = (1 << 16) | (2 << 8); break; + case '1.3': spirv_version_int = (1 << 16) | (3 << 8); break; + case '1.4': spirv_version_int = (1 << 16) | (4 << 8); break; + case '1.5': spirv_version_int = (1 << 16) | (5 << 8); break; + default: + throw new Error("spirv_version must be '1.0' ~ '1.5'."); } var p_output = Module['_malloc'](4); var p_output_len = Module['_malloc'](4); var id = ccall('convert_glsl_to_spirv', 'number', - ['string', 'number', 'boolean', 'number', 'number'], - [glsl, shader_stage_int, gen_debug, p_output, p_output_len]); + ['string', 'number', 'boolean', 'number', 'number', 'number'], + [glsl, shader_stage_int, gen_debug, spirv_version_int, p_output, p_output_len]); var output = getValue(p_output, 'i32'); var output_len = getValue(p_output_len, 'i32'); Module['_free'](p_output); @@ -37,8 +48,8 @@ Module['compileGLSLZeroCopy'] = function(glsl, shader_stage, gen_debug) { return ret; }; -Module['compileGLSL'] = function(glsl, shader_stage, gen_debug) { - var compiled = Module['compileGLSLZeroCopy'](glsl, shader_stage, gen_debug); +Module['compileGLSL'] = function(glsl, shader_stage, gen_debug, spirv_version) { + var compiled = Module['compileGLSLZeroCopy'](glsl, shader_stage, gen_debug, spirv_version); var ret = compiled['data'].slice() compiled['free'](); return ret; diff --git a/src/libraries/glslang/glslang/Public/ShaderLang.h b/src/libraries/glslang/glslang/Public/ShaderLang.h index 4cc6c2f48..273f1569a 100644 --- a/src/libraries/glslang/glslang/Public/ShaderLang.h +++ b/src/libraries/glslang/glslang/Public/ShaderLang.h @@ -44,16 +44,25 @@ #include #ifdef _WIN32 -#define C_DECL __cdecl -//#ifdef SH_EXPORTING -// #define SH_IMPORT_EXPORT __declspec(dllexport) -//#else -// #define SH_IMPORT_EXPORT __declspec(dllimport) -//#endif -#define SH_IMPORT_EXPORT + #define C_DECL __cdecl #else -#define SH_IMPORT_EXPORT -#define C_DECL + #define C_DECL +#endif + +#ifdef GLSLANG_IS_SHARED_LIBRARY + #ifdef _WIN32 + #ifdef GLSLANG_EXPORTING + #define GLSLANG_EXPORT __declspec(dllexport) + #else + #define GLSLANG_EXPORT __declspec(dllimport) + #endif + #elif __GNUC__ >= 4 + #define GLSLANG_EXPORT __attribute__((visibility("default"))) + #endif +#endif // GLSLANG_IS_SHARED_LIBRARY + +#ifndef GLSLANG_EXPORT +#define GLSLANG_EXPORT #endif // @@ -65,22 +74,17 @@ extern "C" { #endif -// This should always increase, as some paths to do not consume -// a more major number. -// It should increment by one when new functionality is added. -#define GLSLANG_MINOR_VERSION 13 - // // Call before doing any other compiler/linker operations. // // (Call once per process, not once per thread.) // -SH_IMPORT_EXPORT int ShInitialize(); +GLSLANG_EXPORT int ShInitialize(); // // Call this at process shutdown to clean up memory. // -SH_IMPORT_EXPORT int ShFinalize(); +GLSLANG_EXPORT int ShFinalize(); // // Types of languages the compiler can consume. @@ -92,32 +96,45 @@ typedef enum { EShLangGeometry, EShLangFragment, EShLangCompute, - EShLangRayGenNV, - EShLangIntersectNV, - EShLangAnyHitNV, - EShLangClosestHitNV, - EShLangMissNV, - EShLangCallableNV, + EShLangRayGen, + EShLangRayGenNV = EShLangRayGen, + EShLangIntersect, + EShLangIntersectNV = EShLangIntersect, + EShLangAnyHit, + EShLangAnyHitNV = EShLangAnyHit, + EShLangClosestHit, + EShLangClosestHitNV = EShLangClosestHit, + EShLangMiss, + EShLangMissNV = EShLangMiss, + EShLangCallable, + EShLangCallableNV = EShLangCallable, EShLangTaskNV, EShLangMeshNV, - EShLangCount, + LAST_ELEMENT_MARKER(EShLangCount), } EShLanguage; // would be better as stage, but this is ancient now -typedef enum { +typedef enum : unsigned { EShLangVertexMask = (1 << EShLangVertex), EShLangTessControlMask = (1 << EShLangTessControl), EShLangTessEvaluationMask = (1 << EShLangTessEvaluation), EShLangGeometryMask = (1 << EShLangGeometry), EShLangFragmentMask = (1 << EShLangFragment), EShLangComputeMask = (1 << EShLangCompute), - EShLangRayGenNVMask = (1 << EShLangRayGenNV), - EShLangIntersectNVMask = (1 << EShLangIntersectNV), - EShLangAnyHitNVMask = (1 << EShLangAnyHitNV), - EShLangClosestHitNVMask = (1 << EShLangClosestHitNV), - EShLangMissNVMask = (1 << EShLangMissNV), - EShLangCallableNVMask = (1 << EShLangCallableNV), + EShLangRayGenMask = (1 << EShLangRayGen), + EShLangRayGenNVMask = EShLangRayGenMask, + EShLangIntersectMask = (1 << EShLangIntersect), + EShLangIntersectNVMask = EShLangIntersectMask, + EShLangAnyHitMask = (1 << EShLangAnyHit), + EShLangAnyHitNVMask = EShLangAnyHitMask, + EShLangClosestHitMask = (1 << EShLangClosestHit), + EShLangClosestHitNVMask = EShLangClosestHitMask, + EShLangMissMask = (1 << EShLangMiss), + EShLangMissNVMask = EShLangMissMask, + EShLangCallableMask = (1 << EShLangCallable), + EShLangCallableNVMask = EShLangCallableMask, EShLangTaskNVMask = (1 << EShLangTaskNV), EShLangMeshNVMask = (1 << EShLangMeshNV), + LAST_ELEMENT_MARKER(EShLanguageMaskCount), } EShLanguageMask; namespace glslang { @@ -128,24 +145,29 @@ typedef enum { EShSourceNone, EShSourceGlsl, // GLSL, includes ESSL (OpenGL ES GLSL) EShSourceHlsl, // HLSL + LAST_ELEMENT_MARKER(EShSourceCount), } EShSource; // if EShLanguage were EShStage, this could be EShLanguage instead typedef enum { EShClientNone, // use when there is no client, e.g. for validation EShClientVulkan, EShClientOpenGL, + LAST_ELEMENT_MARKER(EShClientCount), } EShClient; typedef enum { EShTargetNone, EShTargetSpv, // SPIR-V (preferred spelling) EshTargetSpv = EShTargetSpv, // legacy spelling + LAST_ELEMENT_MARKER(EShTargetCount), } EShTargetLanguage; typedef enum { EShTargetVulkan_1_0 = (1 << 22), // Vulkan 1.0 EShTargetVulkan_1_1 = (1 << 22) | (1 << 12), // Vulkan 1.1 + EShTargetVulkan_1_2 = (1 << 22) | (2 << 12), // Vulkan 1.2 EShTargetOpenGL_450 = 450, // OpenGL + LAST_ELEMENT_MARKER(EShTargetClientVersionCount), } EShTargetClientVersion; typedef EShTargetClientVersion EshTargetClientVersion; @@ -157,6 +179,7 @@ typedef enum { EShTargetSpv_1_3 = (1 << 16) | (3 << 8), // SPIR-V 1.3 EShTargetSpv_1_4 = (1 << 16) | (4 << 8), // SPIR-V 1.4 EShTargetSpv_1_5 = (1 << 16) | (5 << 8), // SPIR-V 1.5 + LAST_ELEMENT_MARKER(EShTargetLanguageVersionCount), } EShTargetLanguageVersion; struct TInputLanguage { @@ -186,7 +209,7 @@ struct TEnvironment { TTarget target; // what to generate }; -const char* StageName(EShLanguage); +GLSLANG_EXPORT const char* StageName(EShLanguage); } // end namespace glslang @@ -206,6 +229,7 @@ typedef enum { EShOptNone, EShOptSimple, // Optimizations that can be done quickly EShOptFull, // Optimizations that will take more time + LAST_ELEMENT_MARKER(EshOptLevelCount), } EShOptimizationLevel; // @@ -214,12 +238,13 @@ typedef enum { typedef enum { EShTexSampTransKeep, // keep textures and samplers as is (default) EShTexSampTransUpgradeTextureRemoveSampler, // change texture w/o embeded sampler into sampled texture and throw away all samplers + LAST_ELEMENT_MARKER(EShTexSampTransCount), } EShTextureSamplerTransformMode; // // Message choices for what errors and warnings are given. // -enum EShMessages { +enum EShMessages : unsigned { EShMsgDefault = 0, // default is to give all required errors and extra warnings EShMsgRelaxedErrors = (1 << 0), // be liberal in accepting input EShMsgSuppressWarnings = (1 << 1), // suppress all warnings, except those required by the specification @@ -234,21 +259,26 @@ enum EShMessages { EShMsgDebugInfo = (1 << 10), // save debug information EShMsgHlslEnable16BitTypes = (1 << 11), // enable use of 16-bit types in SPIR-V for HLSL EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages - EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (right now only for samplers) + EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (for samplers and semantics) EShMsgBuiltinSymbolTable = (1 << 14), // print the builtin symbol table + LAST_ELEMENT_MARKER(EShMsgCount), }; // // Options for building reflection // typedef enum { - EShReflectionDefault = 0, // default is original behaviour before options were added - EShReflectionStrictArraySuffix = (1 << 0), // reflection will follow stricter rules for array-of-structs suffixes - EShReflectionBasicArraySuffix = (1 << 1), // arrays of basic types will be appended with [0] as in GL reflection - EShReflectionIntermediateIO = (1 << 2), // reflect inputs and outputs to program, even with no vertex shader - EShReflectionSeparateBuffers = (1 << 3), // buffer variables and buffer blocks are reflected separately - EShReflectionAllBlockVariables = (1 << 4), // reflect all variables in blocks, even if they are inactive - EShReflectionUnwrapIOBlocks = (1 << 5), // unwrap input/output blocks the same as with uniform blocks + EShReflectionDefault = 0, // default is original behaviour before options were added + EShReflectionStrictArraySuffix = (1 << 0), // reflection will follow stricter rules for array-of-structs suffixes + EShReflectionBasicArraySuffix = (1 << 1), // arrays of basic types will be appended with [0] as in GL reflection + EShReflectionIntermediateIO = (1 << 2), // reflect inputs and outputs to program, even with no vertex shader + EShReflectionSeparateBuffers = (1 << 3), // buffer variables and buffer blocks are reflected separately + EShReflectionAllBlockVariables = (1 << 4), // reflect all variables in blocks, even if they are inactive + EShReflectionUnwrapIOBlocks = (1 << 5), // unwrap input/output blocks the same as with uniform blocks + EShReflectionAllIOVariables = (1 << 6), // reflect all input/output variables, even if they are inactive + EShReflectionSharedStd140SSBO = (1 << 7), // Apply std140/shared rules for ubo to ssbo + EShReflectionSharedStd140UBO = (1 << 8), // Apply std140/shared rules for ubo to ssbo + LAST_ELEMENT_MARKER(EShReflectionCount), } EShReflectionOptions; // @@ -280,10 +310,10 @@ typedef void* ShHandle; // Driver calls these to create and destroy compiler/linker // objects. // -SH_IMPORT_EXPORT ShHandle ShConstructCompiler(const EShLanguage, int debugOptions); // one per shader -SH_IMPORT_EXPORT ShHandle ShConstructLinker(const EShExecutable, int debugOptions); // one per shader pair -SH_IMPORT_EXPORT ShHandle ShConstructUniformMap(); // one per uniform namespace (currently entire program object) -SH_IMPORT_EXPORT void ShDestruct(ShHandle); +GLSLANG_EXPORT ShHandle ShConstructCompiler(const EShLanguage, int debugOptions); // one per shader +GLSLANG_EXPORT ShHandle ShConstructLinker(const EShExecutable, int debugOptions); // one per shader pair +GLSLANG_EXPORT ShHandle ShConstructUniformMap(); // one per uniform namespace (currently entire program object) +GLSLANG_EXPORT void ShDestruct(ShHandle); // // The return value of ShCompile is boolean, non-zero indicating @@ -292,7 +322,7 @@ SH_IMPORT_EXPORT void ShDestruct(ShHandle); // The info-log should be written by ShCompile into // ShHandle, so it can answer future queries. // -SH_IMPORT_EXPORT int ShCompile( +GLSLANG_EXPORT int ShCompile( const ShHandle, const char* const shaderStrings[], const int numStrings, @@ -305,7 +335,7 @@ SH_IMPORT_EXPORT int ShCompile( EShMessages messages = EShMsgDefault // warnings and errors ); -SH_IMPORT_EXPORT int ShLinkExt( +GLSLANG_EXPORT int ShLinkExt( const ShHandle, // linker object const ShHandle h[], // compiler objects to link together const int numHandles); @@ -314,26 +344,26 @@ SH_IMPORT_EXPORT int ShLinkExt( // ShSetEncrpytionMethod is a place-holder for specifying // how source code is encrypted. // -SH_IMPORT_EXPORT void ShSetEncryptionMethod(ShHandle); +GLSLANG_EXPORT void ShSetEncryptionMethod(ShHandle); // // All the following return 0 if the information is not // available in the object passed down, or the object is bad. // -SH_IMPORT_EXPORT const char* ShGetInfoLog(const ShHandle); -SH_IMPORT_EXPORT const void* ShGetExecutable(const ShHandle); -SH_IMPORT_EXPORT int ShSetVirtualAttributeBindings(const ShHandle, const ShBindingTable*); // to detect user aliasing -SH_IMPORT_EXPORT int ShSetFixedAttributeBindings(const ShHandle, const ShBindingTable*); // to force any physical mappings +GLSLANG_EXPORT const char* ShGetInfoLog(const ShHandle); +GLSLANG_EXPORT const void* ShGetExecutable(const ShHandle); +GLSLANG_EXPORT int ShSetVirtualAttributeBindings(const ShHandle, const ShBindingTable*); // to detect user aliasing +GLSLANG_EXPORT int ShSetFixedAttributeBindings(const ShHandle, const ShBindingTable*); // to force any physical mappings // // Tell the linker to never assign a vertex attribute to this list of physical attributes // -SH_IMPORT_EXPORT int ShExcludeAttributes(const ShHandle, int *attributes, int count); +GLSLANG_EXPORT int ShExcludeAttributes(const ShHandle, int *attributes, int count); // // Returns the location ID of the named uniform. // Returns -1 if error. // -SH_IMPORT_EXPORT int ShGetUniformLocation(const ShHandle uniformMap, const char* name); +GLSLANG_EXPORT int ShGetUniformLocation(const ShHandle uniformMap, const char* name); #ifdef __cplusplus } // end extern "C" @@ -364,19 +394,27 @@ class TInfoSink; namespace glslang { -const char* GetEsslVersionString(); -const char* GetGlslVersionString(); -int GetKhronosToolId(); +struct Version { + int major; + int minor; + int patch; + const char* flavor; +}; + +GLSLANG_EXPORT Version GetVersion(); +GLSLANG_EXPORT const char* GetEsslVersionString(); +GLSLANG_EXPORT const char* GetGlslVersionString(); +GLSLANG_EXPORT int GetKhronosToolId(); class TIntermediate; class TProgram; class TPoolAllocator; // Call this exactly once per process before using anything else -bool InitializeProcess(); +GLSLANG_EXPORT bool InitializeProcess(); // Call once per process to tear down everything -void FinalizeProcess(); +GLSLANG_EXPORT void FinalizeProcess(); // Resource type for IO resolver enum TResourceType { @@ -389,11 +427,14 @@ enum TResourceType { EResCount }; + // Make one TShader per shader that you will link into a program. Then // - provide the shader through setStrings() or setStringsWithLengths() // - optionally call setEnv*(), see below for more detail // - optionally use setPreamble() to set a special shader string that will be // processed before all others but won't affect the validity of #version +// - optionally call addProcesses() for each setting/transform, +// see comment for class TProcesses // - call parse(): source language and target environment must be selected // either by correct setting of EShMessages sent to parse(), or by // explicitly calling setEnv*() @@ -406,40 +447,41 @@ enum TResourceType { // class TShader { public: - explicit TShader(EShLanguage); - virtual ~TShader(); - void setStrings(const char* const* s, int n); - void setStringsWithLengths(const char* const* s, const int* l, int n); - void setStringsWithLengthsAndNames( + GLSLANG_EXPORT explicit TShader(EShLanguage); + GLSLANG_EXPORT virtual ~TShader(); + GLSLANG_EXPORT void setStrings(const char* const* s, int n); + GLSLANG_EXPORT void setStringsWithLengths( + const char* const* s, const int* l, int n); + GLSLANG_EXPORT void setStringsWithLengthsAndNames( const char* const* s, const int* l, const char* const* names, int n); void setPreamble(const char* s) { preamble = s; } - void setEntryPoint(const char* entryPoint); - void setSourceEntryPoint(const char* sourceEntryPointName); - void addProcesses(const std::vector&); + GLSLANG_EXPORT void setEntryPoint(const char* entryPoint); + GLSLANG_EXPORT void setSourceEntryPoint(const char* sourceEntryPointName); + GLSLANG_EXPORT void addProcesses(const std::vector&); // IO resolver binding data: see comments in ShaderLang.cpp - void setShiftBinding(TResourceType res, unsigned int base); - void setShiftSamplerBinding(unsigned int base); // DEPRECATED: use setShiftBinding - void setShiftTextureBinding(unsigned int base); // DEPRECATED: use setShiftBinding - void setShiftImageBinding(unsigned int base); // DEPRECATED: use setShiftBinding - void setShiftUboBinding(unsigned int base); // DEPRECATED: use setShiftBinding - void setShiftUavBinding(unsigned int base); // DEPRECATED: use setShiftBinding - void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding - void setShiftSsboBinding(unsigned int base); // DEPRECATED: use setShiftBinding - void setShiftBindingForSet(TResourceType res, unsigned int base, unsigned int set); - void setResourceSetBinding(const std::vector& base); - void setAutoMapBindings(bool map); - void setAutoMapLocations(bool map); - void addUniformLocationOverride(const char* name, int loc); - void setUniformLocationBase(int base); - void setInvertY(bool invert); + GLSLANG_EXPORT void setShiftBinding(TResourceType res, unsigned int base); + GLSLANG_EXPORT void setShiftSamplerBinding(unsigned int base); // DEPRECATED: use setShiftBinding + GLSLANG_EXPORT void setShiftTextureBinding(unsigned int base); // DEPRECATED: use setShiftBinding + GLSLANG_EXPORT void setShiftImageBinding(unsigned int base); // DEPRECATED: use setShiftBinding + GLSLANG_EXPORT void setShiftUboBinding(unsigned int base); // DEPRECATED: use setShiftBinding + GLSLANG_EXPORT void setShiftUavBinding(unsigned int base); // DEPRECATED: use setShiftBinding + GLSLANG_EXPORT void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding + GLSLANG_EXPORT void setShiftSsboBinding(unsigned int base); // DEPRECATED: use setShiftBinding + GLSLANG_EXPORT void setShiftBindingForSet(TResourceType res, unsigned int base, unsigned int set); + GLSLANG_EXPORT void setResourceSetBinding(const std::vector& base); + GLSLANG_EXPORT void setAutoMapBindings(bool map); + GLSLANG_EXPORT void setAutoMapLocations(bool map); + GLSLANG_EXPORT void addUniformLocationOverride(const char* name, int loc); + GLSLANG_EXPORT void setUniformLocationBase(int base); + GLSLANG_EXPORT void setInvertY(bool invert); #ifdef ENABLE_HLSL - void setHlslIoMapping(bool hlslIoMap); - void setFlattenUniformArrays(bool flatten); + GLSLANG_EXPORT void setHlslIoMapping(bool hlslIoMap); + GLSLANG_EXPORT void setFlattenUniformArrays(bool flatten); #endif - void setNoStorageFormat(bool useUnknownFormat); - void setNanMinMaxClamp(bool nanMinMaxClamp); - void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode); + GLSLANG_EXPORT void setNoStorageFormat(bool useUnknownFormat); + GLSLANG_EXPORT void setNanMinMaxClamp(bool nanMinMaxClamp); + GLSLANG_EXPORT void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode); // For setting up the environment (cleared to nothingness in the constructor). // These must be called so that parsing is done for the right source language and @@ -579,8 +621,10 @@ public: virtual void releaseInclude(IncludeResult*) override { } }; - bool parse(const TBuiltInResource*, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile, - bool forwardCompatible, EShMessages, Includer&); + GLSLANG_EXPORT bool parse( + const TBuiltInResource*, int defaultVersion, EProfile defaultProfile, + bool forceDefaultVersionAndProfile, bool forwardCompatible, + EShMessages, Includer&); bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile, bool forwardCompatible, EShMessages messages) @@ -603,13 +647,14 @@ public: // NOTE: Doing just preprocessing to obtain a correct preprocessed shader string // is not an officially supported or fully working path. - bool preprocess(const TBuiltInResource* builtInResources, - int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile, - bool forwardCompatible, EShMessages message, std::string* outputString, - Includer& includer); + GLSLANG_EXPORT bool preprocess( + const TBuiltInResource* builtInResources, int defaultVersion, + EProfile defaultProfile, bool forceDefaultVersionAndProfile, + bool forwardCompatible, EShMessages message, std::string* outputString, + Includer& includer); - const char* getInfoLog(); - const char* getInfoDebugLog(); + GLSLANG_EXPORT const char* getInfoLog(); + GLSLANG_EXPORT const char* getInfoDebugLog(); EShLanguage getStage() const { return stage; } TIntermediate* getIntermediate() const { return intermediate; } @@ -628,11 +673,11 @@ protected: // stringNames is the optional names for all the strings. If stringNames // is null, then none of the strings has name. If a certain element in // stringNames is null, then the corresponding string does not have name. - const char* const* strings; + const char* const* strings; // explicit code to compile, see previous comment const int* lengths; const char* const* stringNames; - const char* preamble; - int numStrings; + int numStrings; // size of the above arrays + const char* preamble; // string of implicit code to compile before the explicitly provided code // a function in the source string can be renamed FROM this TO the name given in setEntryPoint. std::string sourceEntryPointName; @@ -645,7 +690,7 @@ private: TShader& operator=(TShader&); }; -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) // // A reflection database and its interface, consistent with the OpenGL API reflection queries. @@ -654,11 +699,11 @@ private: // Data needed for just a single object at the granularity exchanged by the reflection API class TObjectReflection { public: - TObjectReflection(const std::string& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex); + GLSLANG_EXPORT TObjectReflection(const std::string& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex); - const TType* getType() const { return type; } - int getBinding() const; - void dump() const; + GLSLANG_EXPORT const TType* getType() const { return type; } + GLSLANG_EXPORT int getBinding() const; + GLSLANG_EXPORT void dump() const; static TObjectReflection badReflection() { return TObjectReflection(); } std::string name; @@ -669,6 +714,7 @@ public: int counterIndex; int numMembers; int arrayStride; // stride of an array variable + int topLevelArraySize; // size of the top-level variable in a storage buffer member int topLevelArrayStride; // stride of the top-level variable in a storage buffer member EShLanguageMask stages; @@ -762,7 +808,7 @@ public: virtual void addStage(EShLanguage stage) = 0; }; -#endif // GLSLANG_WEB +#endif // !GLSLANG_WEB && !GLSLANG_ANGLE // Make one TProgram per set of shaders that will get linked together. Add all // the shaders that are to be linked together. After calling shader.parse() @@ -772,40 +818,40 @@ public: // class TProgram { public: - TProgram(); - virtual ~TProgram(); + GLSLANG_EXPORT TProgram(); + GLSLANG_EXPORT virtual ~TProgram(); void addShader(TShader* shader) { stages[shader->stage].push_back(shader); } std::list& getShaders(EShLanguage stage) { return stages[stage]; } // Link Validation interface - bool link(EShMessages); - const char* getInfoLog(); - const char* getInfoDebugLog(); + GLSLANG_EXPORT bool link(EShMessages); + GLSLANG_EXPORT const char* getInfoLog(); + GLSLANG_EXPORT const char* getInfoDebugLog(); TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; } -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) // Reflection Interface // call first, to do liveness analysis, index mapping, etc.; returns false on failure - bool buildReflection(int opts = EShReflectionDefault); - unsigned getLocalSize(int dim) const; // return dim'th local size - int getReflectionIndex(const char *name) const; - int getReflectionPipeIOIndex(const char* name, const bool inOrOut) const; - int getNumUniformVariables() const; - const TObjectReflection& getUniform(int index) const; - int getNumUniformBlocks() const; - const TObjectReflection& getUniformBlock(int index) const; - int getNumPipeInputs() const; - const TObjectReflection& getPipeInput(int index) const; - int getNumPipeOutputs() const; - const TObjectReflection& getPipeOutput(int index) const; - int getNumBufferVariables() const; - const TObjectReflection& getBufferVariable(int index) const; - int getNumBufferBlocks() const; - const TObjectReflection& getBufferBlock(int index) const; - int getNumAtomicCounters() const; - const TObjectReflection& getAtomicCounter(int index) const; + GLSLANG_EXPORT bool buildReflection(int opts = EShReflectionDefault); + GLSLANG_EXPORT unsigned getLocalSize(int dim) const; // return dim'th local size + GLSLANG_EXPORT int getReflectionIndex(const char *name) const; + GLSLANG_EXPORT int getReflectionPipeIOIndex(const char* name, const bool inOrOut) const; + GLSLANG_EXPORT int getNumUniformVariables() const; + GLSLANG_EXPORT const TObjectReflection& getUniform(int index) const; + GLSLANG_EXPORT int getNumUniformBlocks() const; + GLSLANG_EXPORT const TObjectReflection& getUniformBlock(int index) const; + GLSLANG_EXPORT int getNumPipeInputs() const; + GLSLANG_EXPORT const TObjectReflection& getPipeInput(int index) const; + GLSLANG_EXPORT int getNumPipeOutputs() const; + GLSLANG_EXPORT const TObjectReflection& getPipeOutput(int index) const; + GLSLANG_EXPORT int getNumBufferVariables() const; + GLSLANG_EXPORT const TObjectReflection& getBufferVariable(int index) const; + GLSLANG_EXPORT int getNumBufferBlocks() const; + GLSLANG_EXPORT const TObjectReflection& getBufferBlock(int index) const; + GLSLANG_EXPORT int getNumAtomicCounters() const; + GLSLANG_EXPORT const TObjectReflection& getAtomicCounter(int index) const; // Legacy Reflection Interface - expressed in terms of above interface @@ -872,22 +918,22 @@ public: // returns a TType* const TType *getAttributeTType(int index) const { return getPipeInput(index).getType(); } - void dumpReflection(); + GLSLANG_EXPORT void dumpReflection(); // I/O mapping: apply base offsets and map live unbound variables // If resolver is not provided it uses the previous approach // and respects auto assignment and offsets. - bool mapIO(TIoMapResolver* pResolver = nullptr, TIoMapper* pIoMapper = nullptr); -#endif + GLSLANG_EXPORT bool mapIO(TIoMapResolver* pResolver = nullptr, TIoMapper* pIoMapper = nullptr); +#endif // !GLSLANG_WEB && !GLSLANG_ANGLE protected: - bool linkStage(EShLanguage, EShMessages); + GLSLANG_EXPORT bool linkStage(EShLanguage, EShMessages); TPoolAllocator* pool; std::list stages[EShLangCount]; TIntermediate* intermediate[EShLangCount]; bool newedIntermediate[EShLangCount]; // track which intermediate were "new" versus reusing a singleton unit in a stage TInfoSink* infoSink; -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) TReflection* reflection; #endif bool linked; diff --git a/src/libraries/glslang/glslang/MachineIndependent/pch.cpp b/src/libraries/glslang/glslang/build_info.h similarity index 51% rename from src/libraries/glslang/glslang/MachineIndependent/pch.cpp rename to src/libraries/glslang/glslang/build_info.h index b7a08654a..319bfa5f7 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/pch.cpp +++ b/src/libraries/glslang/glslang/build_info.h @@ -1,5 +1,5 @@ +// Copyright (C) 2020 The Khronos Group Inc. // -// Copyright (C) 2018 The Khronos Group Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -14,7 +14,7 @@ // disclaimer in the documentation and/or other materials provided // with the distribution. // -// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// Neither the name of The Khronos Group Inc. nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // @@ -30,6 +30,33 @@ // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. -// -#include "pch.h" +#ifndef GLSLANG_BUILD_INFO +#define GLSLANG_BUILD_INFO + +#define GLSLANG_VERSION_MAJOR 11 +#define GLSLANG_VERSION_MINOR 0 +#define GLSLANG_VERSION_PATCH 0 +#define GLSLANG_VERSION_FLAVOR "" + +#define GLSLANG_VERSION_GREATER_THAN(major, minor, patch) \ + (((major) > GLSLANG_VERSION_MAJOR) || ((major) == GLSLANG_VERSION_MAJOR && \ + (((minor) > GLSLANG_VERSION_MINOR) || ((minor) == GLSLANG_VERSION_MINOR && \ + ((patch) > GLSLANG_VERSION_PATCH))))) + +#define GLSLANG_VERSION_GREATER_OR_EQUAL_TO(major, minor, patch) \ + (((major) > GLSLANG_VERSION_MAJOR) || ((major) == GLSLANG_VERSION_MAJOR && \ + (((minor) > GLSLANG_VERSION_MINOR) || ((minor) == GLSLANG_VERSION_MINOR && \ + ((patch) >= GLSLANG_VERSION_PATCH))))) + +#define GLSLANG_VERSION_LESS_THAN(major, minor, patch) \ + (((major) < GLSLANG_VERSION_MAJOR) || ((major) == GLSLANG_VERSION_MAJOR && \ + (((minor) < GLSLANG_VERSION_MINOR) || ((minor) == GLSLANG_VERSION_MINOR && \ + ((patch) < GLSLANG_VERSION_PATCH))))) + +#define GLSLANG_VERSION_LESS_OR_EQUAL_TO(major, minor, patch) \ + (((major) < GLSLANG_VERSION_MAJOR) || ((major) == GLSLANG_VERSION_MAJOR && \ + (((minor) < GLSLANG_VERSION_MINOR) || ((minor) == GLSLANG_VERSION_MINOR && \ + ((patch) <= GLSLANG_VERSION_PATCH))))) + +#endif // GLSLANG_BUILD_INFO diff --git a/src/modules/graphics/ShaderStage.cpp b/src/modules/graphics/ShaderStage.cpp index 8a3132cd5..13b91c127 100644 --- a/src/modules/graphics/ShaderStage.cpp +++ b/src/modules/graphics/ShaderStage.cpp @@ -118,6 +118,7 @@ static const TBuiltInResource defaultTBuiltInResource = { /* .maxTaskWorkGroupSizeY_NV = */ 1, /* .maxTaskWorkGroupSizeZ_NV = */ 1, /* .maxMeshViewCountNV = */ 4, + /* .maxDualSourceDrawBuffersEXT = */ 1, /* .limits = */ { /* .nonInductiveForLoops = */ 1, /* .whileLoops = */ 1, From 6521ebfabc39fcf075d74149cd184ccd3ca87787 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Mon, 12 Oct 2020 18:26:57 -0300 Subject: [PATCH 21/57] use the 12.x branch of megasource for CI builds --- .github/workflows/main.yml | 2 +- extra/appveyor/appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b8845af80..0ac897fa9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -51,7 +51,7 @@ jobs: with: path: megasource repository: love2d/megasource - ref: master + ref: 12.x - name: Checkout uses: actions/checkout@v2 with: diff --git a/extra/appveyor/appveyor.yml b/extra/appveyor/appveyor.yml index a3741bd5a..e5eb8853c 100644 --- a/extra/appveyor/appveyor.yml +++ b/extra/appveyor/appveyor.yml @@ -28,7 +28,7 @@ install: - for /D %%i in (*) do @if "%%i" NEQ "love" @move %%i love\%%i - for %%i in (*) do @if "%%i" NEQ "appveyor.yml" @move %%i love\%%i # clone megasource and move into top directory. -- git clone --depth 1 https://github.com/love2d/megasource.git megasource +- git clone --depth 1 --single-branch -branch 12.x https://github.com/love2d/megasource.git megasource - cd megasource - for /D %%i in (*) do @move %%i ..\%%i - for %%i in (*) do @move %%i ..\%%i From 2a45866f0fc87ef33632966cbc6725f19cef47af Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Mon, 12 Oct 2020 18:29:18 -0300 Subject: [PATCH 22/57] Fix git command... --- extra/appveyor/appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/appveyor/appveyor.yml b/extra/appveyor/appveyor.yml index e5eb8853c..ef690af5e 100644 --- a/extra/appveyor/appveyor.yml +++ b/extra/appveyor/appveyor.yml @@ -28,7 +28,7 @@ install: - for /D %%i in (*) do @if "%%i" NEQ "love" @move %%i love\%%i - for %%i in (*) do @if "%%i" NEQ "appveyor.yml" @move %%i love\%%i # clone megasource and move into top directory. -- git clone --depth 1 --single-branch -branch 12.x https://github.com/love2d/megasource.git megasource +- git clone --depth 1 --single-branch --branch 12.x https://github.com/love2d/megasource.git megasource - cd megasource - for /D %%i in (*) do @move %%i ..\%%i - for %%i in (*) do @move %%i ..\%%i From 0ad34a3c71e3e9a9e3f7e1cdf34eada99876a83d Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Sun, 11 Oct 2020 10:45:37 +0100 Subject: [PATCH 23/57] System.cpp: Do not require posix_spawn on "Linux" Many libc implementations do not implement posix_spawn. Allow love2d to build without it. --- src/modules/system/System.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/modules/system/System.cpp b/src/modules/system/System.cpp index fd7500c27..8439c0cd7 100644 --- a/src/modules/system/System.cpp +++ b/src/modules/system/System.cpp @@ -39,7 +39,18 @@ #if defined(LOVE_ANDROID) #include "common/android.h" #elif defined(LOVE_LINUX) + +#ifdef __has_include +#if __has_include() +#define LOVE_HAS_POSIX_SPAWN +#endif +#endif + +#ifdef LOVE_HAS_POSIX_SPAWN #include +#else +#include +#endif #endif namespace love @@ -70,10 +81,12 @@ std::string System::getOS() const #endif } +#ifdef LOVE_HAS_POSIX_SPAWN extern "C" { extern char **environ; // The environment, always available } +#endif bool System::openURL(const std::string &url) const { @@ -104,10 +117,19 @@ bool System::openURL(const std::string &url) const pid_t pid; const char *argv[] = {"xdg-open", url.c_str(), nullptr}; +#ifdef LOVE_HAS_POSIX_SPAWN // Note: at the moment this process inherits our file descriptors. // Note: the below const_cast is really ugly as well. if (posix_spawnp(&pid, "xdg-open", nullptr, nullptr, const_cast(argv), environ) != 0) return false; +#else + pid = fork(); + if (pid == 0) + { + execvp("xdg-open", const_cast(argv)); + return false; + } +#endif // Check if xdg-open already completed (or failed.) int status = 0; From 2b0f8495bf5f41936bbf0519a2a56908be756dd4 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Fri, 16 Oct 2020 21:19:50 -0300 Subject: [PATCH 24/57] Fix a crash in Text:set. Fixes issue #1639 --- src/modules/graphics/Text.cpp | 4 ---- src/modules/graphics/Text.h | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/modules/graphics/Text.cpp b/src/modules/graphics/Text.cpp index 3b3d54d57..8d3fa6dd5 100644 --- a/src/modules/graphics/Text.cpp +++ b/src/modules/graphics/Text.cpp @@ -33,7 +33,6 @@ love::Type Text::type("Text", &Drawable::type); Text::Text(Font *font, const std::vector &text) : font(font) , vertexAttributes(Font::vertexFormat, 0) - , vertex_buffer(nullptr) , vert_offset(0) , texture_cache_id((uint32) -1) { @@ -42,8 +41,6 @@ Text::Text(Font *font, const std::vector &text) Text::~Text() { - if (vertex_buffer) - vertex_buffer->release(); } void Text::uploadVertices(const std::vector &vertices, size_t vertoffset) @@ -68,7 +65,6 @@ void Text::uploadVertices(const std::vector &vertices, size_t if (vertex_buffer != nullptr) vertex_buffer->copyTo(0, vertex_buffer->getSize(), new_buffer, 0); - vertex_buffer->release(); vertex_buffer = new_buffer; vertexBuffers.set(0, vertex_buffer, 0); diff --git a/src/modules/graphics/Text.h b/src/modules/graphics/Text.h index 0e3259919..ca55ec44e 100644 --- a/src/modules/graphics/Text.h +++ b/src/modules/graphics/Text.h @@ -88,7 +88,7 @@ private: VertexAttributes vertexAttributes; BufferBindings vertexBuffers; - Buffer *vertex_buffer; + StrongRef vertex_buffer; std::vector draw_commands; From 77f238767f50bcafc099973fd2494398227e4434 Mon Sep 17 00:00:00 2001 From: Garrett Brown Date: Sat, 17 Oct 2020 22:15:18 -0400 Subject: [PATCH 25/57] Update to box2d 2.4.1 --- src/libraries/box2d/b2_api.h | 52 ++++ src/libraries/box2d/b2_block_allocator.h | 5 +- src/libraries/box2d/b2_body.h | 31 ++- src/libraries/box2d/b2_broad_phase.h | 5 +- src/libraries/box2d/b2_chain_shape.h | 3 +- src/libraries/box2d/b2_circle_shape.h | 3 +- src/libraries/box2d/b2_collision.h | 38 +-- src/libraries/box2d/b2_common.h | 138 +++++++++++ src/libraries/box2d/b2_contact.h | 39 ++- src/libraries/box2d/b2_contact_manager.h | 5 +- src/libraries/box2d/b2_distance.h | 21 +- src/libraries/box2d/b2_distance_joint.h | 64 +++-- src/libraries/box2d/b2_draw.h | 11 +- src/libraries/box2d/b2_dynamic_tree.h | 8 +- src/libraries/box2d/b2_edge_shape.h | 7 +- src/libraries/box2d/b2_fixture.h | 47 +++- src/libraries/box2d/b2_friction_joint.h | 5 +- src/libraries/box2d/b2_gear_joint.h | 5 +- src/libraries/box2d/b2_growable_stack.h | 3 +- src/libraries/box2d/b2_joint.h | 28 +-- src/libraries/box2d/b2_math.h | 31 +-- src/libraries/box2d/b2_motor_joint.h | 7 +- src/libraries/box2d/b2_mouse_joint.h | 7 +- src/libraries/box2d/b2_polygon_shape.h | 3 +- src/libraries/box2d/b2_prismatic_joint.h | 5 +- src/libraries/box2d/b2_pulley_joint.h | 7 +- src/libraries/box2d/b2_revolute_joint.h | 7 +- src/libraries/box2d/b2_rope.h | 15 +- src/libraries/box2d/b2_settings.h | 208 ++++++++-------- src/libraries/box2d/b2_shape.h | 7 +- src/libraries/box2d/b2_stack_allocator.h | 5 +- src/libraries/box2d/b2_time_of_impact.h | 7 +- src/libraries/box2d/b2_time_step.h | 11 +- src/libraries/box2d/b2_timer.h | 3 +- src/libraries/box2d/b2_types.h | 33 +++ src/libraries/box2d/b2_weld_joint.h | 7 +- src/libraries/box2d/b2_wheel_joint.h | 5 +- src/libraries/box2d/b2_world.h | 7 +- src/libraries/box2d/b2_world_callbacks.h | 13 +- src/libraries/box2d/collision/b2_distance.cpp | 2 +- .../box2d/collision/b2_dynamic_tree.cpp | 2 - .../box2d/collision/b2_time_of_impact.cpp | 6 +- src/libraries/box2d/common/b2_settings.cpp | 17 +- src/libraries/box2d/dynamics/b2_body.cpp | 3 + src/libraries/box2d/dynamics/b2_contact.cpp | 1 + .../box2d/dynamics/b2_contact_solver.cpp | 5 +- .../box2d/dynamics/b2_contact_solver.h | 1 + .../box2d/dynamics/b2_distance_joint.cpp | 225 +++++++++++++++--- src/libraries/box2d/dynamics/b2_fixture.cpp | 3 +- .../box2d/dynamics/b2_gear_joint.cpp | 6 + src/libraries/box2d/dynamics/b2_joint.cpp | 12 - .../box2d/dynamics/b2_prismatic_joint.cpp | 3 +- .../box2d/dynamics/b2_revolute_joint.cpp | 2 +- .../box2d/dynamics/b2_wheel_joint.cpp | 2 +- src/libraries/box2d/rope/b2_rope.cpp | 40 ++++ src/modules/physics/box2d/Body.cpp | 4 +- src/modules/physics/box2d/Fixture.cpp | 4 +- src/modules/physics/box2d/Joint.cpp | 2 +- 58 files changed, 879 insertions(+), 367 deletions(-) create mode 100644 src/libraries/box2d/b2_api.h create mode 100644 src/libraries/box2d/b2_common.h create mode 100644 src/libraries/box2d/b2_types.h diff --git a/src/libraries/box2d/b2_api.h b/src/libraries/box2d/b2_api.h new file mode 100644 index 000000000..6730203c6 --- /dev/null +++ b/src/libraries/box2d/b2_api.h @@ -0,0 +1,52 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_API_H +#define B2_API_H + +#ifdef B2_SHARED + #if defined _WIN32 || defined __CYGWIN__ + #ifdef box2d_EXPORTS + #ifdef __GNUC__ + #define B2_API __attribute__ ((dllexport)) + #else + #define B2_API __declspec(dllexport) + #endif + #else + #ifdef __GNUC__ + #define B2_API __attribute__ ((dllimport)) + #else + #define B2_API __declspec(dllimport) + #endif + #endif + #else + #if __GNUC__ >= 4 + #define B2_API __attribute__ ((visibility ("default"))) + #else + #define B2_API + #endif + #endif +#else + #define B2_API +#endif + +#endif diff --git a/src/libraries/box2d/b2_block_allocator.h b/src/libraries/box2d/b2_block_allocator.h index 48957343e..95c12de89 100644 --- a/src/libraries/box2d/b2_block_allocator.h +++ b/src/libraries/box2d/b2_block_allocator.h @@ -23,7 +23,8 @@ #ifndef B2_BLOCK_ALLOCATOR_H #define B2_BLOCK_ALLOCATOR_H -#include "box2d/b2_settings.h" +#include "b2_api.h" +#include "b2_settings.h" const int32 b2_blockSizeCount = 14; @@ -33,7 +34,7 @@ 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 +class B2_API b2BlockAllocator { public: b2BlockAllocator(); diff --git a/src/libraries/box2d/b2_body.h b/src/libraries/box2d/b2_body.h index 6ba8574de..565f23898 100644 --- a/src/libraries/box2d/b2_body.h +++ b/src/libraries/box2d/b2_body.h @@ -23,6 +23,7 @@ #ifndef B2_BODY_H #define B2_BODY_H +#include "b2_api.h" #include "b2_math.h" #include "b2_shape.h" @@ -44,19 +45,15 @@ 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 +struct B2_API 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); @@ -121,14 +118,14 @@ struct b2BodyDef bool enabled; /// Use this to store application specific body data. - void* userData; + b2BodyUserData userData; /// Scale the gravity applied to this body. float gravityScale; }; /// A rigid body. These are created via b2World::CreateBody. -class b2Body +class B2_API b2Body { public: /// Creates a fixture and attach it to this body. Use this function if you need @@ -379,10 +376,10 @@ public: const b2Body* GetNext() const; /// Get the user data pointer that was provided in the body definition. - void* GetUserData() const; + b2BodyUserData& GetUserData(); /// Set the user data. Use this to store your application specific data. - void SetUserData(void* data); + void SetUserData(b2BodyUserData& data); /// Get the parent world of this body. b2World* GetWorld(); @@ -398,7 +395,7 @@ private: friend class b2ContactManager; friend class b2ContactSolver; friend class b2Contact; - + friend class b2DistanceJoint; friend class b2FrictionJoint; friend class b2GearJoint; @@ -471,7 +468,7 @@ private: float m_sleepTime; - void* m_userData; + b2BodyUserData m_userData; }; inline b2BodyType b2Body::GetType() const @@ -734,16 +731,16 @@ inline const b2Body* b2Body::GetNext() const return m_next; } -inline void b2Body::SetUserData(void* data) -{ - m_userData = data; -} - -inline void* b2Body::GetUserData() const +inline b2BodyUserData& b2Body::GetUserData() { return m_userData; } +inline void b2Body::SetUserData(b2BodyUserData& userData) +{ + m_userData = userData; +} + inline void b2Body::ApplyForce(const b2Vec2& force, const b2Vec2& point, bool wake) { if (m_type != b2_dynamicBody) diff --git a/src/libraries/box2d/b2_broad_phase.h b/src/libraries/box2d/b2_broad_phase.h index cf1cf6773..cc882ab47 100644 --- a/src/libraries/box2d/b2_broad_phase.h +++ b/src/libraries/box2d/b2_broad_phase.h @@ -23,11 +23,12 @@ #ifndef B2_BROAD_PHASE_H #define B2_BROAD_PHASE_H +#include "b2_api.h" #include "b2_settings.h" #include "b2_collision.h" #include "b2_dynamic_tree.h" -struct b2Pair +struct B2_API b2Pair { int32 proxyIdA; int32 proxyIdB; @@ -36,7 +37,7 @@ struct b2Pair /// 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 +class B2_API b2BroadPhase { public: diff --git a/src/libraries/box2d/b2_chain_shape.h b/src/libraries/box2d/b2_chain_shape.h index 9ba0b8b1c..da2605d62 100644 --- a/src/libraries/box2d/b2_chain_shape.h +++ b/src/libraries/box2d/b2_chain_shape.h @@ -23,6 +23,7 @@ #ifndef B2_CHAIN_SHAPE_H #define B2_CHAIN_SHAPE_H +#include "b2_api.h" #include "b2_shape.h" class b2EdgeShape; @@ -32,7 +33,7 @@ class b2EdgeShape; /// This provides a counter-clockwise winding like the polygon shape. /// Connectivity information is used to create smooth collisions. /// @warning the chain will not collide properly if there are self-intersections. -class b2ChainShape : public b2Shape +class B2_API b2ChainShape : public b2Shape { public: b2ChainShape(); diff --git a/src/libraries/box2d/b2_circle_shape.h b/src/libraries/box2d/b2_circle_shape.h index 009d77db5..5e330f5a7 100644 --- a/src/libraries/box2d/b2_circle_shape.h +++ b/src/libraries/box2d/b2_circle_shape.h @@ -23,10 +23,11 @@ #ifndef B2_CIRCLE_SHAPE_H #define B2_CIRCLE_SHAPE_H +#include "b2_api.h" #include "b2_shape.h" /// A solid circle shape -class b2CircleShape : public b2Shape +class B2_API b2CircleShape : public b2Shape { public: b2CircleShape(); diff --git a/src/libraries/box2d/b2_collision.h b/src/libraries/box2d/b2_collision.h index aaa207b35..4c4592061 100644 --- a/src/libraries/box2d/b2_collision.h +++ b/src/libraries/box2d/b2_collision.h @@ -23,9 +23,11 @@ #ifndef B2_COLLISION_H #define B2_COLLISION_H -#include "b2_math.h" #include +#include "b2_api.h" +#include "b2_math.h" + /// @file /// Structures and functions used for computing contact points, distance /// queries, and TOI queries. @@ -39,7 +41,7 @@ const uint8 b2_nullFeature = UCHAR_MAX; /// The features that intersect to form the contact point /// This must be 4 bytes or less. -struct b2ContactFeature +struct B2_API b2ContactFeature { enum Type { @@ -54,7 +56,7 @@ struct b2ContactFeature }; /// Contact ids to facilitate warm starting. -union b2ContactID +union B2_API b2ContactID { b2ContactFeature cf; uint32 key; ///< Used to quickly compare contact ids. @@ -70,7 +72,7 @@ union b2ContactID /// 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 +struct B2_API b2ManifoldPoint { b2Vec2 localPoint; ///< usage depends on manifold type float normalImpulse; ///< the non-penetration impulse @@ -94,7 +96,7 @@ struct b2ManifoldPoint /// 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 +struct B2_API b2Manifold { enum Type { @@ -111,7 +113,7 @@ struct b2Manifold }; /// This is used to compute the current state of a contact manifold. -struct b2WorldManifold +struct B2_API b2WorldManifold { /// Evaluate the manifold with supplied transforms. This assumes /// modest motion from the original state. This does not change the @@ -137,18 +139,18 @@ enum b2PointState /// 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], +B2_API void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints], const b2Manifold* manifold1, const b2Manifold* manifold2); /// Used for computing contact manifolds. -struct b2ClipVertex +struct B2_API b2ClipVertex { b2Vec2 v; b2ContactID id; }; /// Ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1). -struct b2RayCastInput +struct B2_API b2RayCastInput { b2Vec2 p1, p2; float maxFraction; @@ -156,14 +158,14 @@ struct b2RayCastInput /// Ray-cast output data. The ray hits at p1 + fraction * (p2 - p1), where p1 and p2 /// come from b2RayCastInput. -struct b2RayCastOutput +struct B2_API b2RayCastOutput { b2Vec2 normal; float fraction; }; /// An axis aligned bounding box. -struct b2AABB +struct B2_API b2AABB { /// Verify that the bounds are sorted. bool IsValid() const; @@ -220,36 +222,36 @@ struct b2AABB }; /// Compute the collision manifold between two circles. -void b2CollideCircles(b2Manifold* manifold, +B2_API 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, +B2_API 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, +B2_API 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, +B2_API 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 polygon. -void b2CollideEdgeAndPolygon(b2Manifold* manifold, +B2_API 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], +B2_API int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2], const b2Vec2& normal, float offset, int32 vertexIndexA); /// Determine if two generic shapes overlap. -bool b2TestOverlap( const b2Shape* shapeA, int32 indexA, +B2_API bool b2TestOverlap( const b2Shape* shapeA, int32 indexA, const b2Shape* shapeB, int32 indexB, const b2Transform& xfA, const b2Transform& xfB); diff --git a/src/libraries/box2d/b2_common.h b/src/libraries/box2d/b2_common.h new file mode 100644 index 000000000..dfca8af1b --- /dev/null +++ b/src/libraries/box2d/b2_common.h @@ -0,0 +1,138 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_COMMON_H +#define B2_COMMON_H + +#include "b2_settings.h" + +#include +#include +#include + +#if !defined(NDEBUG) + #define b2DEBUG +#endif + +#define B2_NOT_USED(x) ((void)(x)) +#define b2Assert(A) assert(A) + +#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 + +/// 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 * b2_lengthUnitsPerMeter) + +/// 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 4.0f + +/// A small length used as a collision and constraint tolerance. Usually it is +/// chosen to be numerically significant, but visually insignificant. In meters. +#define b2_linearSlop (0.005f * b2_lengthUnitsPerMeter) + +/// 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 + +/// The maximum linear position correction used when solving constraints. This helps to +/// prevent overshoot. Meters. +#define b2_maxLinearCorrection (0.2f * b2_lengthUnitsPerMeter) + +/// 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 translation of a body per step. This limit is very large and is used +/// to prevent numerical problems. You shouldn't need to adjust this. Meters. +#define b2_maxTranslation (2.0f * b2_lengthUnitsPerMeter) +#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_toiBaumgarte 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 * b2_lengthUnitsPerMeter) + +/// A body cannot sleep if its angular velocity is above this tolerance. +#define b2_angularSleepTolerance (2.0f / 180.0f * b2_pi) + +/// Dump to a file. Only one dump file allowed at a time. +void b2OpenDump(const char* fileName); +void b2Dump(const char* string, ...); +void b2CloseDump(); + +/// 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 B2_API b2Version b2_version; + +#endif diff --git a/src/libraries/box2d/b2_contact.h b/src/libraries/box2d/b2_contact.h index d4c59c620..de7541f13 100644 --- a/src/libraries/box2d/b2_contact.h +++ b/src/libraries/box2d/b2_contact.h @@ -23,6 +23,7 @@ #ifndef B2_CONTACT_H #define B2_CONTACT_H +#include "b2_api.h" #include "b2_collision.h" #include "b2_fixture.h" #include "b2_math.h" @@ -50,12 +51,18 @@ inline float b2MixRestitution(float restitution1, float restitution2) return restitution1 > restitution2 ? restitution1 : restitution2; } +/// Restitution mixing law. This picks the lowest value. +inline float b2MixRestitutionThreshold(float threshold1, float threshold2) +{ + return threshold1 < threshold2 ? threshold1 : threshold2; +} + typedef b2Contact* b2ContactCreateFcn( b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator); typedef void b2ContactDestroyFcn(b2Contact* contact, b2BlockAllocator* allocator); -struct b2ContactRegister +struct B2_API b2ContactRegister { b2ContactCreateFcn* createFcn; b2ContactDestroyFcn* destroyFcn; @@ -67,7 +74,7 @@ struct b2ContactRegister /// 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 +struct B2_API b2ContactEdge { b2Body* other; ///< provides quick access to the other body attached. b2Contact* contact; ///< the contact @@ -78,7 +85,7 @@ struct b2ContactEdge /// 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 +class B2_API b2Contact { public: @@ -139,6 +146,16 @@ public: /// Reset the restitution to the default value. void ResetRestitution(); + /// Override the default restitution velocity threshold mixture. You can call this in b2ContactListener::PreSolve. + /// The value persists until you set or reset. + void SetRestitutionThreshold(float threshold); + + /// Get the restitution threshold. + float GetRestitutionThreshold() const; + + /// Reset the restitution threshold to the default value. + void ResetRestitutionThreshold(); + /// Set the desired tangent speed for a conveyor belt behavior. In meters per second. void SetTangentSpeed(float speed); @@ -219,6 +236,7 @@ protected: float m_friction; float m_restitution; + float m_restitutionThreshold; float m_tangentSpeed; }; @@ -340,6 +358,21 @@ inline void b2Contact::ResetRestitution() m_restitution = b2MixRestitution(m_fixtureA->m_restitution, m_fixtureB->m_restitution); } +inline void b2Contact::SetRestitutionThreshold(float threshold) +{ + m_restitutionThreshold = threshold; +} + +inline float b2Contact::GetRestitutionThreshold() const +{ + return m_restitutionThreshold; +} + +inline void b2Contact::ResetRestitutionThreshold() +{ + m_restitutionThreshold = b2MixRestitutionThreshold(m_fixtureA->m_restitutionThreshold, m_fixtureB->m_restitutionThreshold); +} + inline void b2Contact::SetTangentSpeed(float speed) { m_tangentSpeed = speed; diff --git a/src/libraries/box2d/b2_contact_manager.h b/src/libraries/box2d/b2_contact_manager.h index efa156847..fbd3b4d40 100644 --- a/src/libraries/box2d/b2_contact_manager.h +++ b/src/libraries/box2d/b2_contact_manager.h @@ -23,6 +23,7 @@ #ifndef B2_CONTACT_MANAGER_H #define B2_CONTACT_MANAGER_H +#include "b2_api.h" #include "b2_broad_phase.h" class b2Contact; @@ -31,7 +32,7 @@ class b2ContactListener; class b2BlockAllocator; // Delegate of b2World. -class b2ContactManager +class B2_API b2ContactManager { public: b2ContactManager(); @@ -44,7 +45,7 @@ public: void Destroy(b2Contact* c); void Collide(); - + b2BroadPhase m_broadPhase; b2Contact* m_contactList; int32 m_contactCount; diff --git a/src/libraries/box2d/b2_distance.h b/src/libraries/box2d/b2_distance.h index 3fcefc413..3e05773de 100644 --- a/src/libraries/box2d/b2_distance.h +++ b/src/libraries/box2d/b2_distance.h @@ -23,13 +23,14 @@ #ifndef B2_DISTANCE_H #define B2_DISTANCE_H +#include "b2_api.h" #include "b2_math.h" class b2Shape; /// A distance proxy is used by the GJK algorithm. /// It encapsulates any shape. -struct b2DistanceProxy +struct B2_API b2DistanceProxy { b2DistanceProxy() : m_vertices(nullptr), m_count(0), m_radius(0.0f) {} @@ -61,7 +62,7 @@ struct b2DistanceProxy /// Used to warm start b2Distance. /// Set count to zero on first call. -struct b2SimplexCache +struct B2_API b2SimplexCache { float metric; ///< length or area uint16 count; @@ -71,8 +72,8 @@ struct b2SimplexCache /// Input for b2Distance. /// You have to option to use the shape radii -/// in the computation. Even -struct b2DistanceInput +/// in the computation. Even +struct B2_API b2DistanceInput { b2DistanceProxy proxyA; b2DistanceProxy proxyB; @@ -82,7 +83,7 @@ struct b2DistanceInput }; /// Output for b2Distance. -struct b2DistanceOutput +struct B2_API b2DistanceOutput { b2Vec2 pointA; ///< closest point on shapeA b2Vec2 pointB; ///< closest point on shapeB @@ -93,12 +94,12 @@ struct b2DistanceOutput /// 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, +B2_API void b2Distance(b2DistanceOutput* output, + b2SimplexCache* cache, const b2DistanceInput* input); /// Input parameters for b2ShapeCast -struct b2ShapeCastInput +struct B2_API b2ShapeCastInput { b2DistanceProxy proxyA; b2DistanceProxy proxyB; @@ -108,7 +109,7 @@ struct b2ShapeCastInput }; /// Output results for b2ShapeCast -struct b2ShapeCastOutput +struct B2_API b2ShapeCastOutput { b2Vec2 point; b2Vec2 normal; @@ -118,7 +119,7 @@ struct b2ShapeCastOutput /// Perform a linear shape cast of shape B moving and shape A fixed. Determines the hit point, normal, and translation fraction. /// @returns true if hit, false if there is no hit or an initial overlap -bool b2ShapeCast(b2ShapeCastOutput* output, const b2ShapeCastInput* input); +B2_API bool b2ShapeCast(b2ShapeCastOutput* output, const b2ShapeCastInput* input); ////////////////////////////////////////////////////////////////////////// diff --git a/src/libraries/box2d/b2_distance_joint.h b/src/libraries/box2d/b2_distance_joint.h index b339e9239..cfc75fefb 100644 --- a/src/libraries/box2d/b2_distance_joint.h +++ b/src/libraries/box2d/b2_distance_joint.h @@ -23,14 +23,14 @@ #ifndef B2_DISTANCE_JOINT_H #define B2_DISTANCE_JOINT_H +#include "b2_api.h" #include "b2_joint.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 +/// bodies and the non-zero distance 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. +struct B2_API b2DistanceJointDef : public b2JointDef { b2DistanceJointDef() { @@ -38,12 +38,14 @@ struct b2DistanceJointDef : public b2JointDef localAnchorA.Set(0.0f, 0.0f); localAnchorB.Set(0.0f, 0.0f); length = 1.0f; + minLength = 0.0f; + maxLength = FLT_MAX; stiffness = 0.0f; damping = 0.0f; } - /// Initialize the bodies, anchors, and length using the world - /// anchors. + /// Initialize the bodies, anchors, and rest length using world space anchors. + /// The minimum and maximum lengths are set to the rest length. void Initialize(b2Body* bodyA, b2Body* bodyB, const b2Vec2& anchorA, const b2Vec2& anchorB); @@ -53,10 +55,16 @@ struct b2DistanceJointDef : public b2JointDef /// The local anchor point relative to bodyB's origin. b2Vec2 localAnchorB; - /// The natural length between the anchor points. + /// The rest length of this joint. Clamped to a stable minimum value. float length; - /// The linear stiffness in N/m. A value of 0 disables softness. + /// Minimum length. Clamped to a stable minimum value. + float minLength; + + /// Maximum length. Must be greater than or equal to the minimum length. + float maxLength; + + /// The linear stiffness in N/m. float stiffness; /// The linear damping in N*s/m. @@ -65,7 +73,7 @@ struct b2DistanceJointDef : public b2JointDef /// 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 +class B2_API b2DistanceJoint : public b2Joint { public: @@ -86,11 +94,30 @@ public: /// 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(float length) { m_length = length; } + /// Get the rest length float GetLength() const { return m_length; } + /// Set the rest length + /// @returns clamped rest length + float SetLength(float length); + + /// Get the minimum length + float GetMinLength() const { return m_minLength; } + + /// Set the minimum length + /// @returns the clamped minimum length + float SetMinLength(float minLength); + + /// Get the maximum length + float GetMaxLength() const { return m_maxLength; } + + /// Set the maximum length + /// @returns the clamped maximum length + float SetMaxLength(float maxLength); + + /// Get the current length + float GetCurrentLength() const; + /// Set/get the linear stiffness in N/m void SetStiffness(float stiffness) { m_stiffness = stiffness; } float GetStiffness() const { return m_stiffness; } @@ -102,6 +129,9 @@ public: /// Dump joint to dmLog void Dump() override; + /// + void Draw(b2Draw* draw) const override; + protected: friend class b2Joint; @@ -114,13 +144,17 @@ protected: float m_stiffness; float m_damping; float m_bias; + float m_length; + float m_minLength; + float m_maxLength; // Solver shared b2Vec2 m_localAnchorA; b2Vec2 m_localAnchorB; float m_gamma; float m_impulse; - float m_length; + float m_lowerImpulse; + float m_upperImpulse; // Solver temp int32 m_indexA; @@ -130,10 +164,12 @@ protected: b2Vec2 m_rB; b2Vec2 m_localCenterA; b2Vec2 m_localCenterB; + float m_currentLength; float m_invMassA; float m_invMassB; float m_invIA; float m_invIB; + float m_softMass; float m_mass; }; diff --git a/src/libraries/box2d/b2_draw.h b/src/libraries/box2d/b2_draw.h index 10cbf866f..a4d171187 100644 --- a/src/libraries/box2d/b2_draw.h +++ b/src/libraries/box2d/b2_draw.h @@ -23,10 +23,11 @@ #ifndef B2_DRAW_H #define B2_DRAW_H +#include "b2_api.h" #include "b2_math.h" /// Color for debug drawing. Each value has the range [0,1]. -struct b2Color +struct B2_API b2Color { b2Color() {} b2Color(float rIn, float gIn, float bIn, float aIn = 1.0f) @@ -44,7 +45,7 @@ struct b2Color /// Implement and register this class with a b2World to provide debug drawing of physics /// entities in your game. -class b2Draw +class B2_API b2Draw { public: b2Draw(); @@ -65,7 +66,7 @@ public: /// Get the drawing flags. uint32 GetFlags() const; - + /// Append flags to the current flags. void AppendFlags(uint32 flags); @@ -80,10 +81,10 @@ public: /// Draw a circle. virtual void DrawCircle(const b2Vec2& center, float radius, const b2Color& color) = 0; - + /// Draw a solid circle. virtual void DrawSolidCircle(const b2Vec2& center, float 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; diff --git a/src/libraries/box2d/b2_dynamic_tree.h b/src/libraries/box2d/b2_dynamic_tree.h index b3ddb97ca..b85491915 100644 --- a/src/libraries/box2d/b2_dynamic_tree.h +++ b/src/libraries/box2d/b2_dynamic_tree.h @@ -23,13 +23,14 @@ #ifndef B2_DYNAMIC_TREE_H #define B2_DYNAMIC_TREE_H +#include "b2_api.h" #include "b2_collision.h" #include "b2_growable_stack.h" #define b2_nullNode (-1) /// A node in the dynamic tree. The client does not interact with this directly. -struct b2TreeNode +struct B2_API b2TreeNode { bool IsLeaf() const { @@ -64,7 +65,7 @@ struct b2TreeNode /// 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 +class B2_API b2DynamicTree { public: /// Constructing the tree initializes the node pool. @@ -156,9 +157,6 @@ private: int32 m_freeList; - /// This is used to incrementally traverse the tree for re-balancing. - uint32 m_path; - int32 m_insertionCount; }; diff --git a/src/libraries/box2d/b2_edge_shape.h b/src/libraries/box2d/b2_edge_shape.h index ed79b43e2..b930ee872 100644 --- a/src/libraries/box2d/b2_edge_shape.h +++ b/src/libraries/box2d/b2_edge_shape.h @@ -23,12 +23,13 @@ #ifndef B2_EDGE_SHAPE_H #define B2_EDGE_SHAPE_H +#include "b2_api.h" #include "b2_shape.h" /// A line segment (edge) shape. These can be connected in chains or loops /// to other edge shapes. Edges created independently are two-sided and do -/// no provide smooth movement across junctions. -class b2EdgeShape : public b2Shape +/// no provide smooth movement across junctions. +class B2_API b2EdgeShape : public b2Shape { public: b2EdgeShape(); @@ -60,7 +61,7 @@ public: /// @see b2Shape::ComputeMass void ComputeMass(b2MassData* massData, float density) const override; - + /// These are the edge vertices b2Vec2 m_vertex1, m_vertex2; diff --git a/src/libraries/box2d/b2_fixture.h b/src/libraries/box2d/b2_fixture.h index 4cdde74d8..989dc6bd0 100644 --- a/src/libraries/box2d/b2_fixture.h +++ b/src/libraries/box2d/b2_fixture.h @@ -23,6 +23,7 @@ #ifndef B2_FIXTURE_H #define B2_FIXTURE_H +#include "b2_api.h" #include "b2_body.h" #include "b2_collision.h" #include "b2_shape.h" @@ -33,7 +34,7 @@ class b2BroadPhase; class b2Fixture; /// This holds contact filtering data. -struct b2Filter +struct B2_API b2Filter { b2Filter() { @@ -57,15 +58,15 @@ struct b2Filter /// A fixture definition is used to create a fixture. This class defines an /// abstract fixture definition. You can reuse fixture definitions safely. -struct b2FixtureDef +struct B2_API b2FixtureDef { /// The constructor sets the default fixture definition values. b2FixtureDef() { shape = nullptr; - userData = nullptr; friction = 0.2f; restitution = 0.0f; + restitutionThreshold = 1.0f * b2_lengthUnitsPerMeter; density = 0.0f; isSensor = false; } @@ -75,7 +76,7 @@ struct b2FixtureDef const b2Shape* shape; /// Use this to store application specific fixture data. - void* userData; + b2FixtureUserData userData; /// The friction coefficient, usually in the range [0,1]. float friction; @@ -83,6 +84,10 @@ struct b2FixtureDef /// The restitution (elasticity) usually in the range [0,1]. float restitution; + /// Restitution velocity threshold, usually in m/s. Collisions above this + /// speed have restitution applied (will bounce). + float restitutionThreshold; + /// The density, usually in kg/m^2. float density; @@ -95,7 +100,7 @@ struct b2FixtureDef }; /// This proxy is used internally to connect fixtures to the broad-phase. -struct b2FixtureProxy +struct B2_API b2FixtureProxy { b2AABB aabb; b2Fixture* fixture; @@ -108,7 +113,7 @@ struct b2FixtureProxy /// such as friction, collision filters, etc. /// Fixtures are created via b2Body::CreateFixture. /// @warning you cannot reuse fixtures. -class b2Fixture +class B2_API b2Fixture { public: /// Get the type of the child shape. You can use this to down cast to the concrete shape. @@ -151,10 +156,10 @@ public: /// Get the user data that was assigned in the fixture definition. Use this to /// store your application specific data. - void* GetUserData() const; + b2FixtureUserData& GetUserData(); /// Set the user data. Use this to store your application specific data. - void SetUserData(void* data); + void SetUserData(b2FixtureUserData& userData); /// Test a point for containment in this fixture. /// @param p a point in world coordinates. @@ -192,6 +197,13 @@ public: /// existing contacts. void SetRestitution(float restitution); + /// Get the restitution velocity threshold. + float GetRestitutionThreshold() const; + + /// Set the restitution threshold. This will _not_ change the restitution threshold of + /// existing contacts. + void SetRestitutionThreshold(float threshold); + /// 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. @@ -229,6 +241,7 @@ protected: float m_friction; float m_restitution; + float m_restitutionThreshold; b2FixtureProxy* m_proxies; int32 m_proxyCount; @@ -237,7 +250,7 @@ protected: bool m_isSensor; - void* m_userData; + b2FixtureUserData m_userData; }; inline b2Shape::Type b2Fixture::GetType() const @@ -265,14 +278,14 @@ inline const b2Filter& b2Fixture::GetFilterData() const return m_filter; } -inline void* b2Fixture::GetUserData() const +inline b2FixtureUserData& b2Fixture::GetUserData() { return m_userData; } -inline void b2Fixture::SetUserData(void* data) +inline void b2Fixture::SetUserData(b2FixtureUserData& userData) { - m_userData = data; + m_userData = userData; } inline b2Body* b2Fixture::GetBody() @@ -326,6 +339,16 @@ inline void b2Fixture::SetRestitution(float restitution) m_restitution = restitution; } +inline float b2Fixture::GetRestitutionThreshold() const +{ + return m_restitutionThreshold; +} + +inline void b2Fixture::SetRestitutionThreshold(float threshold) +{ + m_restitutionThreshold = threshold; +} + inline bool b2Fixture::TestPoint(const b2Vec2& p) const { return m_shape->TestPoint(m_body->GetTransform(), p); diff --git a/src/libraries/box2d/b2_friction_joint.h b/src/libraries/box2d/b2_friction_joint.h index d7b88245e..99922c3a3 100644 --- a/src/libraries/box2d/b2_friction_joint.h +++ b/src/libraries/box2d/b2_friction_joint.h @@ -23,10 +23,11 @@ #ifndef B2_FRICTION_JOINT_H #define B2_FRICTION_JOINT_H +#include "b2_api.h" #include "b2_joint.h" /// Friction joint definition. -struct b2FrictionJointDef : public b2JointDef +struct B2_API b2FrictionJointDef : public b2JointDef { b2FrictionJointDef() { @@ -56,7 +57,7 @@ struct b2FrictionJointDef : public b2JointDef /// Friction joint. This is used for top-down friction. /// It provides 2D translational friction and angular friction. -class b2FrictionJoint : public b2Joint +class B2_API b2FrictionJoint : public b2Joint { public: b2Vec2 GetAnchorA() const override; diff --git a/src/libraries/box2d/b2_gear_joint.h b/src/libraries/box2d/b2_gear_joint.h index 69e67a199..1c40687a0 100644 --- a/src/libraries/box2d/b2_gear_joint.h +++ b/src/libraries/box2d/b2_gear_joint.h @@ -27,7 +27,8 @@ /// Gear joint definition. This definition requires two existing /// revolute or prismatic joints (any combination will work). -struct b2GearJointDef : public b2JointDef +/// @warning bodyB on the input joints must both be dynamic +struct B2_API b2GearJointDef : public b2JointDef { b2GearJointDef() { @@ -57,7 +58,7 @@ struct b2GearJointDef : public b2JointDef /// 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 +class B2_API b2GearJoint : public b2Joint { public: b2Vec2 GetAnchorA() const override; diff --git a/src/libraries/box2d/b2_growable_stack.h b/src/libraries/box2d/b2_growable_stack.h index a24984f0c..ec42e5e9e 100644 --- a/src/libraries/box2d/b2_growable_stack.h +++ b/src/libraries/box2d/b2_growable_stack.h @@ -23,9 +23,10 @@ #ifndef B2_GROWABLE_STACK_H #define B2_GROWABLE_STACK_H -#include "b2_settings.h" #include +#include "b2_settings.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. diff --git a/src/libraries/box2d/b2_joint.h b/src/libraries/box2d/b2_joint.h index c33ec90af..c6546663d 100644 --- a/src/libraries/box2d/b2_joint.h +++ b/src/libraries/box2d/b2_joint.h @@ -23,6 +23,7 @@ #ifndef B2_JOINT_H #define B2_JOINT_H +#include "b2_api.h" #include "b2_math.h" class b2Body; @@ -47,7 +48,7 @@ enum b2JointType e_motorJoint }; -struct b2Jacobian +struct B2_API b2Jacobian { b2Vec2 linear; float angularA; @@ -59,7 +60,7 @@ struct b2Jacobian /// 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 +struct B2_API b2JointEdge { b2Body* other; ///< provides quick access to the other body attached. b2Joint* joint; ///< the joint @@ -68,12 +69,11 @@ struct b2JointEdge }; /// Joint definitions are used to construct joints. -struct b2JointDef +struct B2_API b2JointDef { b2JointDef() { type = e_unknownJoint; - userData = nullptr; bodyA = nullptr; bodyB = nullptr; collideConnected = false; @@ -83,7 +83,7 @@ struct b2JointDef b2JointType type; /// Use this to attach application specific data to your joints. - void* userData; + b2JointUserData userData; /// The first attached body. b2Body* bodyA; @@ -96,18 +96,18 @@ struct b2JointDef }; /// Utility to compute linear stiffness values from frequency and damping ratio -void b2LinearStiffness(float& stiffness, float& damping, +B2_API void b2LinearStiffness(float& stiffness, float& damping, float frequencyHertz, float dampingRatio, const b2Body* bodyA, const b2Body* bodyB); /// Utility to compute rotational stiffness values frequency and damping ratio -void b2AngularStiffness(float& stiffness, float& damping, +B2_API void b2AngularStiffness(float& stiffness, float& damping, float frequencyHertz, float dampingRatio, const b2Body* bodyA, const b2Body* bodyB); /// The base joint class. Joints are used to constraint two bodies together in /// various fashions. Some joints also feature limits and motors. -class b2Joint +class B2_API b2Joint { public: @@ -137,10 +137,10 @@ public: const b2Joint* GetNext() const; /// Get the user data pointer. - void* GetUserData() const; + b2JointUserData& GetUserData(); /// Set the user data pointer. - void SetUserData(void* data); + void SetUserData(b2JointUserData& userData); /// Short-cut function to determine if either body is enabled. bool IsEnabled() const; @@ -190,7 +190,7 @@ protected: bool m_islandFlag; bool m_collideConnected; - void* m_userData; + b2JointUserData m_userData; }; inline b2JointType b2Joint::GetType() const @@ -218,14 +218,14 @@ inline const b2Joint* b2Joint::GetNext() const return m_next; } -inline void* b2Joint::GetUserData() const +inline b2JointUserData& b2Joint::GetUserData() { return m_userData; } -inline void b2Joint::SetUserData(void* data) +inline void b2Joint::SetUserData(b2JointUserData& userData) { - m_userData = data; + m_userData = userData; } inline bool b2Joint::GetCollideConnected() const diff --git a/src/libraries/box2d/b2_math.h b/src/libraries/box2d/b2_math.h index f3042ec22..479e667be 100644 --- a/src/libraries/box2d/b2_math.h +++ b/src/libraries/box2d/b2_math.h @@ -23,20 +23,22 @@ #ifndef B2_MATH_H #define B2_MATH_H +#include + +#include "b2_api.h" #include "b2_settings.h" -#include /// This function is used to ensure that a floating point number is not a NaN or infinity. inline bool b2IsValid(float x) { - return std::isfinite(x); + return isfinite(x); } #define b2Sqrt(x) sqrtf(x) #define b2Atan2(y, x) atan2f(y, x) /// A 2D column vector. -struct b2Vec2 +struct B2_API b2Vec2 { /// Default constructor does nothing (for performance). b2Vec2() {} @@ -52,7 +54,7 @@ struct b2Vec2 /// Negate this vector. b2Vec2 operator -() const { b2Vec2 v; v.Set(-x, -y); return v; } - + /// Read from and indexed element. float operator () (int32 i) const { @@ -70,7 +72,7 @@ struct b2Vec2 { x += v.x; y += v.y; } - + /// Subtract a vector from this vector. void operator -= (const b2Vec2& v) { @@ -127,7 +129,7 @@ struct b2Vec2 }; /// A 2D column vector with 3 elements. -struct b2Vec3 +struct B2_API b2Vec3 { /// Default constructor does nothing (for performance). b2Vec3() {} @@ -166,7 +168,7 @@ struct b2Vec3 }; /// A 2-by-2 matrix. Stored in column-major order. -struct b2Mat22 +struct B2_API b2Mat22 { /// The default constructor does nothing (for performance). b2Mat22() {} @@ -240,7 +242,7 @@ struct b2Mat22 }; /// A 3-by-3 matrix. Stored in column-major order. -struct b2Mat33 +struct B2_API b2Mat33 { /// The default constructor does nothing (for performance). b2Mat33() {} @@ -282,7 +284,7 @@ struct b2Mat33 }; /// Rotation -struct b2Rot +struct B2_API b2Rot { b2Rot() {} @@ -333,7 +335,7 @@ struct b2Rot /// A transform contains translation and rotation. It is used to represent /// the position and orientation of rigid frames. -struct b2Transform +struct B2_API b2Transform { /// The default constructor does nothing. b2Transform() {} @@ -363,7 +365,7 @@ struct b2Transform /// 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 +struct B2_API b2Sweep { /// Get the interpolated transform at a specific time. /// @param transform the output transform @@ -387,7 +389,7 @@ struct b2Sweep }; /// Useful constant -extern const b2Vec2 b2Vec2_zero; +extern B2_API const b2Vec2 b2Vec2_zero; /// Perform the dot product on two vectors. inline float b2Dot(const b2Vec2& a, const b2Vec2& b) @@ -681,10 +683,11 @@ inline bool b2IsPowerOfTwo(uint32 x) return result; } +// https://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/ inline void b2Sweep::GetTransform(b2Transform* xf, float beta) const { - xf->p = c0 + beta * (c - c0); - float angle = a0 + beta * (a - a0); + xf->p = (1.0f - beta) * c0 + beta * c; + float angle = (1.0f - beta) * a0 + beta * a; xf->q.Set(angle); // Shift to origin diff --git a/src/libraries/box2d/b2_motor_joint.h b/src/libraries/box2d/b2_motor_joint.h index c3f1adcbb..c88115f20 100644 --- a/src/libraries/box2d/b2_motor_joint.h +++ b/src/libraries/box2d/b2_motor_joint.h @@ -23,10 +23,11 @@ #ifndef B2_MOTOR_JOINT_H #define B2_MOTOR_JOINT_H +#include "b2_api.h" #include "b2_joint.h" /// Motor joint definition. -struct b2MotorJointDef : public b2JointDef +struct B2_API b2MotorJointDef : public b2JointDef { b2MotorJointDef() { @@ -46,7 +47,7 @@ struct b2MotorJointDef : public b2JointDef /// The bodyB angle minus bodyA angle in radians. float angularOffset; - + /// The maximum motor force in N. float maxForce; @@ -60,7 +61,7 @@ struct b2MotorJointDef : public b2JointDef /// 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 +class B2_API b2MotorJoint : public b2Joint { public: b2Vec2 GetAnchorA() const override; diff --git a/src/libraries/box2d/b2_mouse_joint.h b/src/libraries/box2d/b2_mouse_joint.h index ebaa02592..fcbc56a70 100644 --- a/src/libraries/box2d/b2_mouse_joint.h +++ b/src/libraries/box2d/b2_mouse_joint.h @@ -23,11 +23,12 @@ #ifndef B2_MOUSE_JOINT_H #define B2_MOUSE_JOINT_H +#include "b2_api.h" #include "b2_joint.h" /// Mouse joint definition. This requires a world target point, /// tuning parameters, and the time step. -struct b2MouseJointDef : public b2JointDef +struct B2_API b2MouseJointDef : public b2JointDef { b2MouseJointDef() { @@ -61,7 +62,7 @@ struct b2MouseJointDef : public b2JointDef /// 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 +class B2_API b2MouseJoint : public b2Joint { public: @@ -113,7 +114,7 @@ protected: float m_stiffness; float m_damping; float m_beta; - + // Solver shared b2Vec2 m_impulse; float m_maxForce; diff --git a/src/libraries/box2d/b2_polygon_shape.h b/src/libraries/box2d/b2_polygon_shape.h index 52f4cc0ec..5a4e563f8 100644 --- a/src/libraries/box2d/b2_polygon_shape.h +++ b/src/libraries/box2d/b2_polygon_shape.h @@ -22,13 +22,14 @@ #ifndef B2_POLYGON_SHAPE_H #define B2_POLYGON_SHAPE_H +#include "b2_api.h" #include "b2_shape.h" /// A solid 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 +class B2_API b2PolygonShape : public b2Shape { public: b2PolygonShape(); diff --git a/src/libraries/box2d/b2_prismatic_joint.h b/src/libraries/box2d/b2_prismatic_joint.h index 09cbad540..9d12d2126 100644 --- a/src/libraries/box2d/b2_prismatic_joint.h +++ b/src/libraries/box2d/b2_prismatic_joint.h @@ -23,6 +23,7 @@ #ifndef B2_PRISMATIC_JOINT_H #define B2_PRISMATIC_JOINT_H +#include "b2_api.h" #include "b2_joint.h" /// Prismatic joint definition. This requires defining a line of @@ -31,7 +32,7 @@ /// 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 +struct B2_API b2PrismaticJointDef : public b2JointDef { b2PrismaticJointDef() { @@ -87,7 +88,7 @@ struct b2PrismaticJointDef : public b2JointDef /// 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 +class B2_API b2PrismaticJoint : public b2Joint { public: b2Vec2 GetAnchorA() const override; diff --git a/src/libraries/box2d/b2_pulley_joint.h b/src/libraries/box2d/b2_pulley_joint.h index 14f12c41f..6b1445641 100644 --- a/src/libraries/box2d/b2_pulley_joint.h +++ b/src/libraries/box2d/b2_pulley_joint.h @@ -23,13 +23,14 @@ #ifndef B2_PULLEY_JOINT_H #define B2_PULLEY_JOINT_H +#include "b2_api.h" #include "b2_joint.h" const float 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 +struct B2_API b2PulleyJointDef : public b2JointDef { b2PulleyJointDef() { @@ -80,7 +81,7 @@ struct b2PulleyJointDef : public b2JointDef /// 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 +class B2_API b2PulleyJoint : public b2Joint { public: b2Vec2 GetAnchorA() const override; @@ -129,7 +130,7 @@ protected: b2Vec2 m_groundAnchorB; float m_lengthA; float m_lengthB; - + // Solver shared b2Vec2 m_localAnchorA; b2Vec2 m_localAnchorB; diff --git a/src/libraries/box2d/b2_revolute_joint.h b/src/libraries/box2d/b2_revolute_joint.h index f202e3551..36ad5314e 100644 --- a/src/libraries/box2d/b2_revolute_joint.h +++ b/src/libraries/box2d/b2_revolute_joint.h @@ -23,6 +23,7 @@ #ifndef B2_REVOLUTE_JOINT_H #define B2_REVOLUTE_JOINT_H +#include "b2_api.h" #include "b2_joint.h" /// Revolute joint definition. This requires defining an anchor point where the @@ -35,7 +36,7 @@ /// 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 +struct B2_API b2RevoluteJointDef : public b2JointDef { b2RevoluteJointDef() { @@ -90,7 +91,7 @@ struct b2RevoluteJointDef : public b2JointDef /// 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 +class B2_API b2RevoluteJoint : public b2Joint { public: b2Vec2 GetAnchorA() const override; @@ -161,7 +162,7 @@ public: void Draw(b2Draw* draw) const override; protected: - + friend class b2Joint; friend class b2GearJoint; diff --git a/src/libraries/box2d/b2_rope.h b/src/libraries/box2d/b2_rope.h index 5f1cc4073..47f5fc442 100644 --- a/src/libraries/box2d/b2_rope.h +++ b/src/libraries/box2d/b2_rope.h @@ -23,6 +23,7 @@ #ifndef B2_ROPE_H #define B2_ROPE_H +#include "b2_api.h" #include "b2_math.h" class b2Draw; @@ -41,11 +42,12 @@ enum b2BendingModel b2_pbdAngleBendingModel, b2_xpbdAngleBendingModel, b2_pbdDistanceBendingModel, - b2_pbdHeightBendingModel + b2_pbdHeightBendingModel, + b2_pbdTriangleBendingModel }; /// -struct b2RopeTuning +struct B2_API b2RopeTuning { b2RopeTuning() { @@ -75,8 +77,8 @@ struct b2RopeTuning bool warmStart; }; -/// -struct b2RopeDef +/// +struct B2_API b2RopeDef { b2RopeDef() { @@ -95,8 +97,8 @@ struct b2RopeDef b2RopeTuning tuning; }; -/// -class b2Rope +/// +class B2_API b2Rope { public: b2Rope(); @@ -125,6 +127,7 @@ private: void SolveBend_XPBD_Angle(float dt); void SolveBend_PBD_Distance(); void SolveBend_PBD_Height(); + void SolveBend_PBD_Triangle(); void ApplyBendForces(float dt); b2Vec2 m_position; diff --git a/src/libraries/box2d/b2_settings.h b/src/libraries/box2d/b2_settings.h index 8695980e1..ccdcac519 100644 --- a/src/libraries/box2d/b2_settings.h +++ b/src/libraries/box2d/b2_settings.h @@ -23,143 +23,123 @@ #ifndef B2_SETTINGS_H #define B2_SETTINGS_H -#include -#include -#include - -void loveAssert(bool test, const char* teststr); - -#if !defined(NDEBUG) - #define b2DEBUG -#endif - -#define B2_NOT_USED(x) ((void)(x)) -//#define b2Assert(A) assert(A) -#define b2Assert(A) loveAssert((A), #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; - -#define b2_maxFloat FLT_MAX -#define b2_epsilon FLT_EPSILON -#define b2_pi 3.14159265359f +#include "b2_types.h" +#include "b2_api.h" /// @file -/// Global tuning constants based on meters-kilograms-seconds (MKS) units. +/// Settings that can be overriden for your application /// -// Collision +/// Define this macro in your build if you want to override settings +#ifdef B2_USER_SETTINGS -/// The maximum number of contact points between two convex shapes. Do -/// not change this value. -#define b2_maxManifoldPoints 2 +/// This is a user file that includes custom definitions of the macros, structs, and functions +/// defined below. +#include "b2_user_settings.h" + +#else + +#include +#include + +// Tunable Constants + +/// You can use this to change the length scale used by your game. +/// For example for inches you could use 39.4. +#define b2_lengthUnitsPerMeter 1.0f /// 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 +// User data -/// 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 4.0f +/// You can define this to inject whatever data you want in b2Body +struct B2_API b2BodyUserData +{ + b2BodyUserData() + { + pointer = 0; + } -/// 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 + /// For legacy compatibility + uintptr_t pointer; +}; -/// 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) +/// You can define this to inject whatever data you want in b2Fixture +struct B2_API b2FixtureUserData +{ + b2FixtureUserData() + { + pointer = 0; + } -/// 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) + /// For legacy compatibility + uintptr_t pointer; +}; -/// Maximum number of sub-steps per contact in continuous physics simulation. -#define b2_maxSubSteps 8 +/// You can define this to inject whatever data you want in b2Joint +struct B2_API b2JointUserData +{ + b2JointUserData() + { + pointer = 0; + } - -// 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_toiBaumgarte 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) + /// For legacy compatibility + uintptr_t pointer; +}; // Memory Allocation +/// Default allocation functions +B2_API void* b2Alloc_Default(int32 size); +B2_API void b2Free_Default(void* mem); + /// Implement this function to use your own memory allocator. -void* b2Alloc(int32 size); +inline void* b2Alloc(int32 size) +{ + return b2Alloc_Default(size); +} /// If you implement b2Alloc, you should also implement this function. -void b2Free(void* mem); - -/// Logging function. -void b2Log(const char* string, ...); - -/// Dump to a file. Only one dump file allowed at a time. -void b2OpenDump(const char* fileName); -void b2Dump(const char* string, ...); -void b2CloseDump(); - -/// Version numbering scheme. -/// See http://en.wikipedia.org/wiki/Software_versioning -struct b2Version +inline void b2Free(void* mem) { - int32 major; ///< significant changes - int32 minor; ///< incremental changes - int32 revision; ///< bug fixes -}; + b2Free_Default(mem); +} -/// Current version. -extern b2Version b2_version; +/// Default logging function +B2_API void b2Log_Default(const char* string, va_list args); + +/// Implement this to use your own logging. +inline void b2Log(const char* string, ...) +{ + va_list args; + va_start(args, string); + b2Log_Default(string, args); + va_end(args); +} + +#endif // B2_USER_SETTINGS + +void loveAssert(bool test, const char* teststr); + +#define b2Assert(A) loveAssert((A), #A) + +namespace love { + namespace physics { + namespace box2d { + struct bodyudata; + struct fixtureudata; + struct jointudata; + } + } +} + +#define b2BodyUserData love::physics::box2d::bodyudata* +#define b2FixtureUserData love::physics::box2d::fixtureudata* +#define b2JointUserData love::physics::box2d::jointudata* + +#include "b2_common.h" #endif diff --git a/src/libraries/box2d/b2_shape.h b/src/libraries/box2d/b2_shape.h index 27e3d14bc..cbed2b863 100644 --- a/src/libraries/box2d/b2_shape.h +++ b/src/libraries/box2d/b2_shape.h @@ -23,13 +23,14 @@ #ifndef B2_SHAPE_H #define B2_SHAPE_H +#include "b2_api.h" #include "b2_math.h" #include "b2_collision.h" class b2BlockAllocator; /// This holds the mass data computed for a shape. -struct b2MassData +struct B2_API b2MassData { /// The mass of the shape, usually in kilograms. float mass; @@ -44,10 +45,10 @@ struct b2MassData /// 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 +class B2_API b2Shape { public: - + enum Type { e_circle = 0, diff --git a/src/libraries/box2d/b2_stack_allocator.h b/src/libraries/box2d/b2_stack_allocator.h index 780ab7945..1db2af5d9 100644 --- a/src/libraries/box2d/b2_stack_allocator.h +++ b/src/libraries/box2d/b2_stack_allocator.h @@ -23,12 +23,13 @@ #ifndef B2_STACK_ALLOCATOR_H #define B2_STACK_ALLOCATOR_H +#include "b2_api.h" #include "b2_settings.h" const int32 b2_stackSize = 100 * 1024; // 100k const int32 b2_maxStackEntries = 32; -struct b2StackEntry +struct B2_API b2StackEntry { char* data; int32 size; @@ -38,7 +39,7 @@ struct b2StackEntry // 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 +class B2_API b2StackAllocator { public: b2StackAllocator(); diff --git a/src/libraries/box2d/b2_time_of_impact.h b/src/libraries/box2d/b2_time_of_impact.h index bb3031fcb..04d46262e 100644 --- a/src/libraries/box2d/b2_time_of_impact.h +++ b/src/libraries/box2d/b2_time_of_impact.h @@ -23,11 +23,12 @@ #ifndef B2_TIME_OF_IMPACT_H #define B2_TIME_OF_IMPACT_H +#include "b2_api.h" #include "b2_math.h" #include "b2_distance.h" /// Input parameters for b2TimeOfImpact -struct b2TOIInput +struct B2_API b2TOIInput { b2DistanceProxy proxyA; b2DistanceProxy proxyB; @@ -37,7 +38,7 @@ struct b2TOIInput }; /// Output parameters for b2TimeOfImpact. -struct b2TOIOutput +struct B2_API b2TOIOutput { enum State { @@ -57,6 +58,6 @@ struct b2TOIOutput /// 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); +B2_API void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input); #endif diff --git a/src/libraries/box2d/b2_time_step.h b/src/libraries/box2d/b2_time_step.h index f0304a300..13d6292ec 100644 --- a/src/libraries/box2d/b2_time_step.h +++ b/src/libraries/box2d/b2_time_step.h @@ -22,10 +22,11 @@ #ifndef B2_TIME_STEP_H #define B2_TIME_STEP_H +#include "b2_api.h" #include "b2_math.h" /// Profiling data. Times are in milliseconds. -struct b2Profile +struct B2_API b2Profile { float step; float collide; @@ -38,7 +39,7 @@ struct b2Profile }; /// This is an internal structure. -struct b2TimeStep +struct B2_API b2TimeStep { float dt; // time step float inv_dt; // inverse time step (0 if dt == 0). @@ -49,21 +50,21 @@ struct b2TimeStep }; /// This is an internal structure. -struct b2Position +struct B2_API b2Position { b2Vec2 c; float a; }; /// This is an internal structure. -struct b2Velocity +struct B2_API b2Velocity { b2Vec2 v; float w; }; /// Solver Data -struct b2SolverData +struct B2_API b2SolverData { b2TimeStep step; b2Position* positions; diff --git a/src/libraries/box2d/b2_timer.h b/src/libraries/box2d/b2_timer.h index a664de833..7893c3270 100644 --- a/src/libraries/box2d/b2_timer.h +++ b/src/libraries/box2d/b2_timer.h @@ -23,11 +23,12 @@ #ifndef B2_TIMER_H #define B2_TIMER_H +#include "b2_api.h" #include "b2_settings.h" /// Timer for profiling. This has platform specific code and may /// not work on every platform. -class b2Timer +class B2_API b2Timer { public: diff --git a/src/libraries/box2d/b2_types.h b/src/libraries/box2d/b2_types.h new file mode 100644 index 000000000..e0d437759 --- /dev/null +++ b/src/libraries/box2d/b2_types.h @@ -0,0 +1,33 @@ +// MIT License + +// Copyright (c) 2020 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of 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 B2_TYPES_H +#define B2_TYPES_H + +typedef signed char int8; +typedef signed short int16; +typedef signed int int32; +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; + +#endif diff --git a/src/libraries/box2d/b2_weld_joint.h b/src/libraries/box2d/b2_weld_joint.h index fd5537f34..f226c8a46 100644 --- a/src/libraries/box2d/b2_weld_joint.h +++ b/src/libraries/box2d/b2_weld_joint.h @@ -23,12 +23,13 @@ #ifndef B2_WELD_JOINT_H #define B2_WELD_JOINT_H +#include "b2_api.h" #include "b2_joint.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 +struct B2_API b2WeldJointDef : public b2JointDef { b2WeldJointDef() { @@ -54,7 +55,7 @@ struct b2WeldJointDef : public b2JointDef /// The bodyB angle minus bodyA angle in the reference state (radians). float referenceAngle; - + /// The rotational stiffness in N*m /// Disable softness with a value of 0 float stiffness; @@ -65,7 +66,7 @@ struct b2WeldJointDef : public b2JointDef /// 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 +class B2_API b2WeldJoint : public b2Joint { public: b2Vec2 GetAnchorA() const override; diff --git a/src/libraries/box2d/b2_wheel_joint.h b/src/libraries/box2d/b2_wheel_joint.h index 1b8f43739..8576adbd2 100644 --- a/src/libraries/box2d/b2_wheel_joint.h +++ b/src/libraries/box2d/b2_wheel_joint.h @@ -23,6 +23,7 @@ #ifndef B2_WHEEL_JOINT_H #define B2_WHEEL_JOINT_H +#include "b2_api.h" #include "b2_joint.h" /// Wheel joint definition. This requires defining a line of @@ -31,7 +32,7 @@ /// 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 +struct B2_API b2WheelJointDef : public b2JointDef { b2WheelJointDef() { @@ -91,7 +92,7 @@ struct b2WheelJointDef : public b2JointDef /// 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. The spring/damper is /// initialized upon creation. This joint is designed for vehicle suspensions. -class b2WheelJoint : public b2Joint +class B2_API b2WheelJoint : public b2Joint { public: b2Vec2 GetAnchorA() const override; diff --git a/src/libraries/box2d/b2_world.h b/src/libraries/box2d/b2_world.h index 3ddc136e3..57d37096c 100644 --- a/src/libraries/box2d/b2_world.h +++ b/src/libraries/box2d/b2_world.h @@ -23,6 +23,7 @@ #ifndef B2_WORLD_H #define B2_WORLD_H +#include "b2_api.h" #include "b2_block_allocator.h" #include "b2_contact_manager.h" #include "b2_math.h" @@ -42,7 +43,7 @@ class b2Joint; /// The world class manages all physics entities, dynamic simulation, /// and asynchronous queries. The world also contains efficient memory /// management facilities. -class b2World +class B2_API b2World { public: /// Construct a world object. @@ -58,7 +59,7 @@ public: /// 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. + /// 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 @@ -185,7 +186,7 @@ public: /// Change the global gravity vector. void SetGravity(const b2Vec2& gravity); - + /// Get the global gravity vector. b2Vec2 GetGravity() const; diff --git a/src/libraries/box2d/b2_world_callbacks.h b/src/libraries/box2d/b2_world_callbacks.h index e1e75c9e9..da45640e2 100644 --- a/src/libraries/box2d/b2_world_callbacks.h +++ b/src/libraries/box2d/b2_world_callbacks.h @@ -23,6 +23,7 @@ #ifndef B2_WORLD_CALLBACKS_H #define B2_WORLD_CALLBACKS_H +#include "b2_api.h" #include "b2_settings.h" struct b2Vec2; @@ -37,7 +38,7 @@ 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 +class B2_API b2DestructionListener { public: virtual ~b2DestructionListener() {} @@ -53,7 +54,7 @@ public: /// 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 +class B2_API b2ContactFilter { public: virtual ~b2ContactFilter() {} @@ -66,7 +67,7 @@ public: /// 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 +struct B2_API b2ContactImpulse { float normalImpulses[b2_maxManifoldPoints]; float tangentImpulses[b2_maxManifoldPoints]; @@ -82,7 +83,7 @@ struct b2ContactImpulse /// 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 +class B2_API b2ContactListener { public: virtual ~b2ContactListener() {} @@ -124,7 +125,7 @@ public: /// Callback class for AABB queries. /// See b2World::Query -class b2QueryCallback +class B2_API b2QueryCallback { public: virtual ~b2QueryCallback() {} @@ -136,7 +137,7 @@ public: /// Callback class for ray casts. /// See b2World::RayCast -class b2RayCastCallback +class B2_API b2RayCastCallback { public: virtual ~b2RayCastCallback() {} diff --git a/src/libraries/box2d/collision/b2_distance.cpp b/src/libraries/box2d/collision/b2_distance.cpp index e2a27abd0..244132408 100644 --- a/src/libraries/box2d/collision/b2_distance.cpp +++ b/src/libraries/box2d/collision/b2_distance.cpp @@ -27,7 +27,7 @@ #include "box2d/b2_polygon_shape.h" // GJK using Voronoi regions (Christer Ericson) and Barycentric coordinates. -int32 b2_gjkCalls, b2_gjkIters, b2_gjkMaxIters; +B2_API int32 b2_gjkCalls, b2_gjkIters, b2_gjkMaxIters; void b2DistanceProxy::Set(const b2Shape* shape, int32 index) { diff --git a/src/libraries/box2d/collision/b2_dynamic_tree.cpp b/src/libraries/box2d/collision/b2_dynamic_tree.cpp index 45e093320..55a9d3246 100644 --- a/src/libraries/box2d/collision/b2_dynamic_tree.cpp +++ b/src/libraries/box2d/collision/b2_dynamic_tree.cpp @@ -41,8 +41,6 @@ b2DynamicTree::b2DynamicTree() m_nodes[m_nodeCapacity-1].height = -1; m_freeList = 0; - m_path = 0; - m_insertionCount = 0; } diff --git a/src/libraries/box2d/collision/b2_time_of_impact.cpp b/src/libraries/box2d/collision/b2_time_of_impact.cpp index ca61a31f7..7a1011b7e 100644 --- a/src/libraries/box2d/collision/b2_time_of_impact.cpp +++ b/src/libraries/box2d/collision/b2_time_of_impact.cpp @@ -29,9 +29,9 @@ #include -float b2_toiTime, b2_toiMaxTime; -int32 b2_toiCalls, b2_toiIters, b2_toiMaxIters; -int32 b2_toiRootIters, b2_toiMaxRootIters; +B2_API float b2_toiTime, b2_toiMaxTime; +B2_API int32 b2_toiCalls, b2_toiIters, b2_toiMaxIters; +B2_API int32 b2_toiRootIters, b2_toiMaxRootIters; // struct b2SeparationFunction diff --git a/src/libraries/box2d/common/b2_settings.cpp b/src/libraries/box2d/common/b2_settings.cpp index 2b8565c9e..9b66769ac 100644 --- a/src/libraries/box2d/common/b2_settings.cpp +++ b/src/libraries/box2d/common/b2_settings.cpp @@ -27,28 +27,23 @@ #include #include -#include "common/Exception.h" - b2Version b2_version = {2, 4, 0}; // Memory allocators. Modify these to use your own allocator. -void* b2Alloc(int32 size) +void* b2Alloc_Default(int32 size) { return malloc(size); } -void b2Free(void* mem) +void b2Free_Default(void* mem) { free(mem); } // You can modify this to use your logging facility. -void b2Log(const char* string, ...) +void b2Log_Default(const char* string, va_list args) { - va_list args; - va_start(args, string); vprintf(string, args); - va_end(args); } FILE* b2_dumpFile = nullptr; @@ -77,9 +72,3 @@ void b2CloseDump() fclose(b2_dumpFile); b2_dumpFile = nullptr; } - -void loveAssert(bool test, const char* teststr) -{ - if (!test) - throw love::Exception("Box2D assertion failed: %s", teststr); -} diff --git a/src/libraries/box2d/dynamics/b2_body.cpp b/src/libraries/box2d/dynamics/b2_body.cpp index 39851c4cb..574666442 100644 --- a/src/libraries/box2d/dynamics/b2_body.cpp +++ b/src/libraries/box2d/dynamics/b2_body.cpp @@ -434,6 +434,9 @@ void b2Body::SetTransform(const b2Vec2& position, float angle) { f->Synchronize(broadPhase, m_xf, m_xf); } + + // Check for new contacts the next step + m_world->m_newContacts = true; } void b2Body::SynchronizeFixtures() diff --git a/src/libraries/box2d/dynamics/b2_contact.cpp b/src/libraries/box2d/dynamics/b2_contact.cpp index 7c95649d0..1c65bc895 100644 --- a/src/libraries/box2d/dynamics/b2_contact.cpp +++ b/src/libraries/box2d/dynamics/b2_contact.cpp @@ -156,6 +156,7 @@ b2Contact::b2Contact(b2Fixture* fA, int32 indexA, b2Fixture* fB, int32 indexB) m_friction = b2MixFriction(m_fixtureA->m_friction, m_fixtureB->m_friction); m_restitution = b2MixRestitution(m_fixtureA->m_restitution, m_fixtureB->m_restitution); + m_restitutionThreshold = b2MixRestitutionThreshold(m_fixtureA->m_restitutionThreshold, m_fixtureB->m_restitutionThreshold); m_tangentSpeed = 0.0f; } diff --git a/src/libraries/box2d/dynamics/b2_contact_solver.cpp b/src/libraries/box2d/dynamics/b2_contact_solver.cpp index f60a2086e..e6f432a23 100644 --- a/src/libraries/box2d/dynamics/b2_contact_solver.cpp +++ b/src/libraries/box2d/dynamics/b2_contact_solver.cpp @@ -31,7 +31,7 @@ // 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; +B2_API bool g_blockSolve = true; struct b2ContactPositionConstraint { @@ -80,6 +80,7 @@ b2ContactSolver::b2ContactSolver(b2ContactSolverDef* def) b2ContactVelocityConstraint* vc = m_velocityConstraints + i; vc->friction = contact->m_friction; vc->restitution = contact->m_restitution; + vc->threshold = contact->m_restitutionThreshold; vc->tangentSpeed = contact->m_tangentSpeed; vc->indexA = bodyA->m_islandIndex; vc->indexB = bodyB->m_islandIndex; @@ -213,7 +214,7 @@ void b2ContactSolver::InitializeVelocityConstraints() // Setup a velocity bias for restitution. vcp->velocityBias = 0.0f; float vRel = b2Dot(vc->normal, vB + b2Cross(wB, vcp->rB) - vA - b2Cross(wA, vcp->rA)); - if (vRel < -b2_velocityThreshold) + if (vRel < -vc->threshold) { vcp->velocityBias = -vc->restitution * vRel; } diff --git a/src/libraries/box2d/dynamics/b2_contact_solver.h b/src/libraries/box2d/dynamics/b2_contact_solver.h index bef5e819c..1064738ef 100644 --- a/src/libraries/box2d/dynamics/b2_contact_solver.h +++ b/src/libraries/box2d/dynamics/b2_contact_solver.h @@ -55,6 +55,7 @@ struct b2ContactVelocityConstraint float invIA, invIB; float friction; float restitution; + float threshold; float tangentSpeed; int32 pointCount; int32 contactIndex; diff --git a/src/libraries/box2d/dynamics/b2_distance_joint.cpp b/src/libraries/box2d/dynamics/b2_distance_joint.cpp index 9eea08559..e54dbaf4f 100644 --- a/src/libraries/box2d/dynamics/b2_distance_joint.cpp +++ b/src/libraries/box2d/dynamics/b2_distance_joint.cpp @@ -21,6 +21,7 @@ // SOFTWARE. #include "box2d/b2_body.h" +#include "box2d/b2_draw.h" #include "box2d/b2_distance_joint.h" #include "box2d/b2_time_step.h" @@ -48,7 +49,9 @@ void b2DistanceJointDef::Initialize(b2Body* b1, b2Body* b2, localAnchorA = bodyA->GetLocalPoint(anchor1); localAnchorB = bodyB->GetLocalPoint(anchor2); b2Vec2 d = anchor2 - anchor1; - length = d.Length(); + length = b2Max(d.Length(), b2_linearSlop); + minLength = length; + maxLength = length; } b2DistanceJoint::b2DistanceJoint(const b2DistanceJointDef* def) @@ -56,13 +59,18 @@ b2DistanceJoint::b2DistanceJoint(const b2DistanceJointDef* def) { m_localAnchorA = def->localAnchorA; m_localAnchorB = def->localAnchorB; - m_length = def->length; + m_length = b2Max(def->length, b2_linearSlop); + m_minLength = b2Max(def->minLength, b2_linearSlop); + m_maxLength = b2Max(def->maxLength, m_minLength); m_stiffness = def->stiffness; m_damping = def->damping; - m_impulse = 0.0f; m_gamma = 0.0f; m_bias = 0.0f; + m_impulse = 0.0f; + m_lowerImpulse = 0.0f; + m_upperImpulse = 0.0f; + m_currentLength = 0.0f; } void b2DistanceJoint::InitVelocityConstraints(const b2SolverData& data) @@ -93,23 +101,29 @@ void b2DistanceJoint::InitVelocityConstraints(const b2SolverData& data) m_u = cB + m_rB - cA - m_rA; // Handle singularity. - float length = m_u.Length(); - if (length > b2_linearSlop) + m_currentLength = m_u.Length(); + if (m_currentLength > b2_linearSlop) { - m_u *= 1.0f / length; + m_u *= 1.0f / m_currentLength; } else { m_u.Set(0.0f, 0.0f); + m_mass = 0.0f; + m_impulse = 0.0f; + m_lowerImpulse = 0.0f; + m_upperImpulse = 0.0f; } float crAu = b2Cross(m_rA, m_u); float crBu = b2Cross(m_rB, m_u); float invMass = m_invMassA + m_invIA * crAu * crAu + m_invMassB + m_invIB * crBu * crBu; + m_mass = invMass != 0.0f ? 1.0f / invMass : 0.0f; - if (m_stiffness > 0.0f) + if (m_stiffness > 0.0f && m_minLength < m_maxLength) { - float C = length - m_length; + // soft + float C = m_currentLength - m_length; float d = m_damping; float k = m_stiffness; @@ -117,27 +131,31 @@ void b2DistanceJoint::InitVelocityConstraints(const b2SolverData& data) // magic formulas float h = data.step.dt; - // gamma = 1 / (h * (d + h * k)), the extra factor of h in the denominator is since the lambda is an impulse, not a force + // gamma = 1 / (h * (d + h * k)) + // the extra factor of h in the denominator is since the lambda is an impulse, not a force 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; + m_softMass = invMass != 0.0f ? 1.0f / invMass : 0.0f; } else { + // rigid m_gamma = 0.0f; m_bias = 0.0f; - m_mass = invMass != 0.0f ? 1.0f / invMass : 0.0f; + m_softMass = m_mass; } if (data.step.warmStarting) { // Scale the impulse to support a variable time step. m_impulse *= data.step.dtRatio; + m_lowerImpulse *= data.step.dtRatio; + m_upperImpulse *= data.step.dtRatio; - b2Vec2 P = m_impulse * m_u; + b2Vec2 P = (m_impulse + m_lowerImpulse - m_upperImpulse) * m_u; vA -= m_invMassA * P; wA -= m_invIA * b2Cross(m_rA, P); vB += m_invMassB * P; @@ -161,19 +179,85 @@ void b2DistanceJoint::SolveVelocityConstraints(const b2SolverData& data) b2Vec2 vB = data.velocities[m_indexB].v; float 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); - float Cdot = b2Dot(m_u, vpB - vpA); + if (m_minLength < m_maxLength) + { + if (m_stiffness > 0.0f) + { + // Cdot = dot(u, v + cross(w, r)) + b2Vec2 vpA = vA + b2Cross(wA, m_rA); + b2Vec2 vpB = vB + b2Cross(wB, m_rB); + float Cdot = b2Dot(m_u, vpB - vpA); - float impulse = -m_mass * (Cdot + m_bias + m_gamma * m_impulse); - m_impulse += impulse; + float impulse = -m_softMass * (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); + 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); + } + + // lower + { + float C = m_currentLength - m_minLength; + float bias = b2Max(0.0f, C) * data.step.inv_dt; + + b2Vec2 vpA = vA + b2Cross(wA, m_rA); + b2Vec2 vpB = vB + b2Cross(wB, m_rB); + float Cdot = b2Dot(m_u, vpB - vpA); + + float impulse = -m_mass * (Cdot + bias); + float oldImpulse = m_lowerImpulse; + m_lowerImpulse = b2Max(0.0f, m_lowerImpulse + impulse); + impulse = m_lowerImpulse - 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); + } + + // upper + { + float C = m_maxLength - m_currentLength; + float bias = b2Max(0.0f, C) * data.step.inv_dt; + + b2Vec2 vpA = vA + b2Cross(wA, m_rA); + b2Vec2 vpB = vB + b2Cross(wB, m_rB); + float Cdot = b2Dot(m_u, vpA - vpB); + + float impulse = -m_mass * (Cdot + bias); + float oldImpulse = m_upperImpulse; + m_upperImpulse = b2Max(0.0f, m_upperImpulse + impulse); + impulse = m_upperImpulse - 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); + } + } + else + { + // Equal limits + + // Cdot = dot(u, v + cross(w, r)) + b2Vec2 vpA = vA + b2Cross(wA, m_rA); + b2Vec2 vpB = vB + b2Cross(wB, m_rB); + float Cdot = b2Dot(m_u, vpB - vpA); + + float impulse = -m_mass * Cdot; + 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; @@ -183,12 +267,6 @@ void b2DistanceJoint::SolveVelocityConstraints(const b2SolverData& data) bool b2DistanceJoint::SolvePositionConstraints(const b2SolverData& data) { - if (m_stiffness > 0.0f) - { - // There is no position correction for soft distance constraints. - return true; - } - b2Vec2 cA = data.positions[m_indexA].c; float aA = data.positions[m_indexA].a; b2Vec2 cB = data.positions[m_indexB].c; @@ -201,8 +279,23 @@ bool b2DistanceJoint::SolvePositionConstraints(const b2SolverData& data) b2Vec2 u = cB + rB - cA - rA; float length = u.Normalize(); - float C = length - m_length; - C = b2Clamp(C, -b2_maxLinearCorrection, b2_maxLinearCorrection); + float C; + if (m_minLength == m_maxLength) + { + C = length - m_minLength; + } + else if (length < m_minLength) + { + C = length - m_minLength; + } + else if (m_maxLength < length) + { + C = length - m_maxLength; + } + else + { + return true; + } float impulse = -m_mass * C; b2Vec2 P = impulse * u; @@ -232,7 +325,7 @@ b2Vec2 b2DistanceJoint::GetAnchorB() const b2Vec2 b2DistanceJoint::GetReactionForce(float inv_dt) const { - b2Vec2 F = (inv_dt * m_impulse) * m_u; + b2Vec2 F = inv_dt * (m_impulse + m_lowerImpulse - m_upperImpulse) * m_u; return F; } @@ -242,6 +335,36 @@ float b2DistanceJoint::GetReactionTorque(float inv_dt) const return 0.0f; } +float b2DistanceJoint::SetLength(float length) +{ + m_impulse = 0.0f; + m_length = b2Max(b2_linearSlop, length); + return m_length; +} + +float b2DistanceJoint::SetMinLength(float minLength) +{ + m_lowerImpulse = 0.0f; + m_minLength = b2Clamp(minLength, b2_linearSlop, m_maxLength); + return m_minLength; +} + +float b2DistanceJoint::SetMaxLength(float maxLength) +{ + m_upperImpulse = 0.0f; + m_maxLength = b2Max(maxLength, m_minLength); + return m_maxLength; +} + +float b2DistanceJoint::GetCurrentLength() const +{ + b2Vec2 pA = m_bodyA->GetWorldPoint(m_localAnchorA); + b2Vec2 pB = m_bodyB->GetWorldPoint(m_localAnchorB); + b2Vec2 d = pB - pA; + float length = d.Length(); + return length; +} + void b2DistanceJoint::Dump() { int32 indexA = m_bodyA->m_islandIndex; @@ -254,7 +377,45 @@ void b2DistanceJoint::Dump() b2Dump(" jd.localAnchorA.Set(%.9g, %.9g);\n", m_localAnchorA.x, m_localAnchorA.y); b2Dump(" jd.localAnchorB.Set(%.9g, %.9g);\n", m_localAnchorB.x, m_localAnchorB.y); b2Dump(" jd.length = %.9g;\n", m_length); + b2Dump(" jd.minLength = %.9g;\n", m_minLength); + b2Dump(" jd.maxLength = %.9g;\n", m_maxLength); b2Dump(" jd.stiffness = %.9g;\n", m_stiffness); b2Dump(" jd.damping = %.9g;\n", m_damping); b2Dump(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); } + +void b2DistanceJoint::Draw(b2Draw* draw) const +{ + const b2Transform& xfA = m_bodyA->GetTransform(); + const b2Transform& xfB = m_bodyB->GetTransform(); + b2Vec2 pA = b2Mul(xfA, m_localAnchorA); + b2Vec2 pB = b2Mul(xfB, m_localAnchorB); + + b2Vec2 axis = pB - pA; + float length = axis.Normalize(); + + b2Color c1(0.7f, 0.7f, 0.7f); + b2Color c2(0.3f, 0.9f, 0.3f); + b2Color c3(0.9f, 0.3f, 0.3f); + b2Color c4(0.4f, 0.4f, 0.4f); + + draw->DrawSegment(pA, pB, c4); + + b2Vec2 pRest = pA + m_length * axis; + draw->DrawPoint(pRest, 8.0f, c1); + + if (m_minLength != m_maxLength) + { + if (m_minLength > b2_linearSlop) + { + b2Vec2 pMin = pA + m_minLength * axis; + draw->DrawPoint(pMin, 4.0f, c2); + } + + if (m_maxLength < FLT_MAX) + { + b2Vec2 pMax = pA + m_maxLength * axis; + draw->DrawPoint(pMax, 4.0f, c3); + } + } +} diff --git a/src/libraries/box2d/dynamics/b2_fixture.cpp b/src/libraries/box2d/dynamics/b2_fixture.cpp index 420cfdcfa..9fd700aa9 100644 --- a/src/libraries/box2d/dynamics/b2_fixture.cpp +++ b/src/libraries/box2d/dynamics/b2_fixture.cpp @@ -33,7 +33,6 @@ b2Fixture::b2Fixture() { - m_userData = nullptr; m_body = nullptr; m_next = nullptr; m_proxies = nullptr; @@ -47,6 +46,7 @@ void b2Fixture::Create(b2BlockAllocator* allocator, b2Body* body, const b2Fixtur m_userData = def->userData; m_friction = def->friction; m_restitution = def->restitution; + m_restitutionThreshold = def->restitutionThreshold; m_body = body; m_next = nullptr; @@ -235,6 +235,7 @@ void b2Fixture::Dump(int32 bodyIndex) b2Dump(" b2FixtureDef fd;\n"); b2Dump(" fd.friction = %.9g;\n", m_friction); b2Dump(" fd.restitution = %.9g;\n", m_restitution); + b2Dump(" fd.restitutionThreshold = %.9g;\n", m_restitutionThreshold); b2Dump(" fd.density = %.9g;\n", m_density); b2Dump(" fd.isSensor = bool(%d);\n", m_isSensor); b2Dump(" fd.filter.categoryBits = uint16(%d);\n", m_filter.categoryBits); diff --git a/src/libraries/box2d/dynamics/b2_gear_joint.cpp b/src/libraries/box2d/dynamics/b2_gear_joint.cpp index 414291093..ff36d3e10 100644 --- a/src/libraries/box2d/dynamics/b2_gear_joint.cpp +++ b/src/libraries/box2d/dynamics/b2_gear_joint.cpp @@ -64,6 +64,9 @@ b2GearJoint::b2GearJoint(const b2GearJointDef* def) m_bodyC = m_joint1->GetBodyA(); m_bodyA = m_joint1->GetBodyB(); + // Body B on joint1 must be dynamic + b2Assert(m_bodyA->m_type == b2_dynamicBody); + // Get geometry of joint1 b2Transform xfA = m_bodyA->m_xf; float aA = m_bodyA->m_sweep.a; @@ -96,6 +99,9 @@ b2GearJoint::b2GearJoint(const b2GearJointDef* def) m_bodyD = m_joint2->GetBodyA(); m_bodyB = m_joint2->GetBodyB(); + // Body B on joint2 must be dynamic + b2Assert(m_bodyB->m_type == b2_dynamicBody); + // Get geometry of joint2 b2Transform xfB = m_bodyB->m_xf; float aB = m_bodyB->m_sweep.a; diff --git a/src/libraries/box2d/dynamics/b2_joint.cpp b/src/libraries/box2d/dynamics/b2_joint.cpp index 1f8ac2644..41addbbb2 100644 --- a/src/libraries/box2d/dynamics/b2_joint.cpp +++ b/src/libraries/box2d/dynamics/b2_joint.cpp @@ -31,7 +31,6 @@ #include "box2d/b2_prismatic_joint.h" #include "box2d/b2_pulley_joint.h" #include "box2d/b2_revolute_joint.h" -#include "box2d/b2_rope_joint.h" #include "box2d/b2_weld_joint.h" #include "box2d/b2_wheel_joint.h" #include "box2d/b2_world.h" @@ -157,13 +156,6 @@ b2Joint* b2Joint::Create(const b2JointDef* def, b2BlockAllocator* allocator) } break; - case e_ropeJoint: - { - void* mem = allocator->Allocate(sizeof(b2RopeJoint)); - joint = new (mem) b2RopeJoint(static_cast(def)); - } - break; - case e_motorJoint: { void* mem = allocator->Allocate(sizeof(b2MotorJoint)); @@ -220,10 +212,6 @@ void b2Joint::Destroy(b2Joint* joint, b2BlockAllocator* allocator) allocator->Free(joint, sizeof(b2FrictionJoint)); break; - case e_ropeJoint: - allocator->Free(joint, sizeof(b2RopeJoint)); - break; - case e_motorJoint: allocator->Free(joint, sizeof(b2MotorJoint)); break; diff --git a/src/libraries/box2d/dynamics/b2_prismatic_joint.cpp b/src/libraries/box2d/dynamics/b2_prismatic_joint.cpp index cb550170f..00e77690e 100644 --- a/src/libraries/box2d/dynamics/b2_prismatic_joint.cpp +++ b/src/libraries/box2d/dynamics/b2_prismatic_joint.cpp @@ -462,7 +462,7 @@ b2Vec2 b2PrismaticJoint::GetAnchorB() const b2Vec2 b2PrismaticJoint::GetReactionForce(float inv_dt) const { - return inv_dt * (m_impulse.x * m_perp + (m_motorImpulse + m_lowerImpulse + m_upperImpulse) * m_axis); + return inv_dt * (m_impulse.x * m_perp + (m_motorImpulse + m_lowerImpulse - m_upperImpulse) * m_axis); } float b2PrismaticJoint::GetReactionTorque(float inv_dt) const @@ -607,7 +607,6 @@ void b2PrismaticJoint::Dump() b2Dump(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); } -/// void b2PrismaticJoint::Draw(b2Draw* draw) const { const b2Transform& xfA = m_bodyA->GetTransform(); diff --git a/src/libraries/box2d/dynamics/b2_revolute_joint.cpp b/src/libraries/box2d/dynamics/b2_revolute_joint.cpp index 35162b084..f7cc4cc29 100644 --- a/src/libraries/box2d/dynamics/b2_revolute_joint.cpp +++ b/src/libraries/box2d/dynamics/b2_revolute_joint.cpp @@ -338,7 +338,7 @@ b2Vec2 b2RevoluteJoint::GetReactionForce(float inv_dt) const float b2RevoluteJoint::GetReactionTorque(float inv_dt) const { - return inv_dt * (m_lowerImpulse + m_upperImpulse); + return inv_dt * (m_motorImpulse + m_lowerImpulse - m_upperImpulse); } float b2RevoluteJoint::GetJointAngle() const diff --git a/src/libraries/box2d/dynamics/b2_wheel_joint.cpp b/src/libraries/box2d/dynamics/b2_wheel_joint.cpp index 3e76678bf..c23b98460 100644 --- a/src/libraries/box2d/dynamics/b2_wheel_joint.cpp +++ b/src/libraries/box2d/dynamics/b2_wheel_joint.cpp @@ -455,7 +455,7 @@ b2Vec2 b2WheelJoint::GetAnchorB() const b2Vec2 b2WheelJoint::GetReactionForce(float inv_dt) const { - return inv_dt * (m_impulse * m_ay + m_springImpulse * m_ax); + return inv_dt * (m_impulse * m_ay + (m_springImpulse + m_lowerImpulse - m_upperImpulse) * m_ax); } float b2WheelJoint::GetReactionTorque(float inv_dt) const diff --git a/src/libraries/box2d/rope/b2_rope.cpp b/src/libraries/box2d/rope/b2_rope.cpp index 511944814..d2425a2af 100644 --- a/src/libraries/box2d/rope/b2_rope.cpp +++ b/src/libraries/box2d/rope/b2_rope.cpp @@ -306,6 +306,10 @@ void b2Rope::Step(float dt, int32 iterations, const b2Vec2& position) { SolveBend_PBD_Height(); } + else if (m_tuning.bendingModel == b2_pbdTriangleBendingModel) + { + SolveBend_PBD_Triangle(); + } if (m_tuning.stretchingModel == b2_pbdStretchingModel) { @@ -750,6 +754,42 @@ void b2Rope::SolveBend_PBD_Height() } } +// M. Kelager: A Triangle Bending Constraint Model for PBD +void b2Rope::SolveBend_PBD_Triangle() +{ + const float stiffness = m_tuning.bendStiffness; + + for (int32 i = 0; i < m_bendCount; ++i) + { + const b2RopeBend& c = m_bendConstraints[i]; + + b2Vec2 b0 = m_ps[c.i1]; + b2Vec2 v = m_ps[c.i2]; + b2Vec2 b1 = m_ps[c.i3]; + + float wb0 = c.invMass1; + float wv = c.invMass2; + float wb1 = c.invMass3; + + float W = wb0 + wb1 + 2.0f * wv; + float invW = stiffness / W; + + b2Vec2 d = v - (1.0f / 3.0f) * (b0 + v + b1); + + b2Vec2 db0 = 2.0f * wb0 * invW * d; + b2Vec2 dv = -4.0f * wv * invW * d; + b2Vec2 db1 = 2.0f * wb1 * invW * d; + + b0 += db0; + v += dv; + b1 += db1; + + m_ps[c.i1] = b0; + m_ps[c.i2] = v; + m_ps[c.i3] = b1; + } +} + void b2Rope::Draw(b2Draw* draw) const { b2Color c(0.4f, 0.5f, 0.7f); diff --git a/src/modules/physics/box2d/Body.cpp b/src/modules/physics/box2d/Body.cpp index c61368636..05070d64f 100644 --- a/src/modules/physics/box2d/Body.cpp +++ b/src/modules/physics/box2d/Body.cpp @@ -45,7 +45,7 @@ Body::Body(World *world, b2Vec2 p, Body::Type type) udata->ref = nullptr; b2BodyDef def; def.position = Physics::scaleDown(p); - def.userData = (void *) udata; + def.userData = udata; body = world->world->CreateBody(&def); // Box2D body holds a reference to the love Body. this->retain(); @@ -529,7 +529,7 @@ int Body::setUserData(lua_State *L) if (udata == nullptr) { udata = new bodyudata(); - body->SetUserData((void *) udata); + body->SetUserData(udata); } if(!udata->ref) diff --git a/src/modules/physics/box2d/Fixture.cpp b/src/modules/physics/box2d/Fixture.cpp index 6278eb45f..6595eec1f 100644 --- a/src/modules/physics/box2d/Fixture.cpp +++ b/src/modules/physics/box2d/Fixture.cpp @@ -45,7 +45,7 @@ Fixture::Fixture(Body *body, Shape *shape, float density) udata->ref = nullptr; b2FixtureDef def; def.shape = shape->shape; - def.userData = (void *)udata; + def.userData = udata; def.density = density; fixture = body->body->CreateFixture(&def); this->retain(); @@ -262,7 +262,7 @@ int Fixture::setUserData(lua_State *L) if (udata == nullptr) { udata = new fixtureudata(); - fixture->SetUserData((void *) udata); + fixture->SetUserData(udata); } if(!udata->ref) diff --git a/src/modules/physics/box2d/Joint.cpp b/src/modules/physics/box2d/Joint.cpp index b1d8cccaa..a2e735fa3 100644 --- a/src/modules/physics/box2d/Joint.cpp +++ b/src/modules/physics/box2d/Joint.cpp @@ -202,7 +202,7 @@ int Joint::setUserData(lua_State *L) if (udata == nullptr) { udata = new jointudata(); - joint->SetUserData((void *) udata); + joint->SetUserData(udata); } if(!udata->ref) From 1b74b34cceb14be2eaa65478452e618df60150a7 Mon Sep 17 00:00:00 2001 From: Garrett Brown Date: Sat, 17 Oct 2020 22:30:01 -0400 Subject: [PATCH 26/57] Update userdata stuff to how new box2d wants it --- src/libraries/box2d/b2_body.h | 7 +------ src/libraries/box2d/b2_fixture.h | 8 -------- src/libraries/box2d/b2_joint.h | 8 -------- src/libraries/box2d/b2_settings.h | 15 --------------- src/modules/physics/box2d/Body.cpp | 4 ++-- src/modules/physics/box2d/Fixture.cpp | 4 ++-- src/modules/physics/box2d/Joint.cpp | 4 ++-- 7 files changed, 7 insertions(+), 43 deletions(-) diff --git a/src/libraries/box2d/b2_body.h b/src/libraries/box2d/b2_body.h index 565f23898..f1038202b 100644 --- a/src/libraries/box2d/b2_body.h +++ b/src/libraries/box2d/b2_body.h @@ -379,7 +379,7 @@ public: b2BodyUserData& GetUserData(); /// Set the user data. Use this to store your application specific data. - void SetUserData(b2BodyUserData& data); + void SetUserData(void* data); /// Get the parent world of this body. b2World* GetWorld(); @@ -736,11 +736,6 @@ inline b2BodyUserData& b2Body::GetUserData() return m_userData; } -inline void b2Body::SetUserData(b2BodyUserData& userData) -{ - m_userData = userData; -} - inline void b2Body::ApplyForce(const b2Vec2& force, const b2Vec2& point, bool wake) { if (m_type != b2_dynamicBody) diff --git a/src/libraries/box2d/b2_fixture.h b/src/libraries/box2d/b2_fixture.h index 989dc6bd0..f12789b5e 100644 --- a/src/libraries/box2d/b2_fixture.h +++ b/src/libraries/box2d/b2_fixture.h @@ -158,9 +158,6 @@ public: /// store your application specific data. b2FixtureUserData& GetUserData(); - /// Set the user data. Use this to store your application specific data. - void SetUserData(b2FixtureUserData& userData); - /// Test a point for containment in this fixture. /// @param p a point in world coordinates. bool TestPoint(const b2Vec2& p) const; @@ -283,11 +280,6 @@ inline b2FixtureUserData& b2Fixture::GetUserData() return m_userData; } -inline void b2Fixture::SetUserData(b2FixtureUserData& userData) -{ - m_userData = userData; -} - inline b2Body* b2Fixture::GetBody() { return m_body; diff --git a/src/libraries/box2d/b2_joint.h b/src/libraries/box2d/b2_joint.h index c6546663d..2b4d586cd 100644 --- a/src/libraries/box2d/b2_joint.h +++ b/src/libraries/box2d/b2_joint.h @@ -139,9 +139,6 @@ public: /// Get the user data pointer. b2JointUserData& GetUserData(); - /// Set the user data pointer. - void SetUserData(b2JointUserData& userData); - /// Short-cut function to determine if either body is enabled. bool IsEnabled() const; @@ -223,11 +220,6 @@ inline b2JointUserData& b2Joint::GetUserData() return m_userData; } -inline void b2Joint::SetUserData(b2JointUserData& userData) -{ - m_userData = userData; -} - inline bool b2Joint::GetCollideConnected() const { return m_collideConnected; diff --git a/src/libraries/box2d/b2_settings.h b/src/libraries/box2d/b2_settings.h index ccdcac519..6db959ada 100644 --- a/src/libraries/box2d/b2_settings.h +++ b/src/libraries/box2d/b2_settings.h @@ -123,23 +123,8 @@ inline void b2Log(const char* string, ...) #endif // B2_USER_SETTINGS void loveAssert(bool test, const char* teststr); - #define b2Assert(A) loveAssert((A), #A) -namespace love { - namespace physics { - namespace box2d { - struct bodyudata; - struct fixtureudata; - struct jointudata; - } - } -} - -#define b2BodyUserData love::physics::box2d::bodyudata* -#define b2FixtureUserData love::physics::box2d::fixtureudata* -#define b2JointUserData love::physics::box2d::jointudata* - #include "b2_common.h" #endif diff --git a/src/modules/physics/box2d/Body.cpp b/src/modules/physics/box2d/Body.cpp index 05070d64f..8859c8bc8 100644 --- a/src/modules/physics/box2d/Body.cpp +++ b/src/modules/physics/box2d/Body.cpp @@ -45,7 +45,7 @@ Body::Body(World *world, b2Vec2 p, Body::Type type) udata->ref = nullptr; b2BodyDef def; def.position = Physics::scaleDown(p); - def.userData = udata; + def.userData.pointer = (uintptr_t)udata; body = world->world->CreateBody(&def); // Box2D body holds a reference to the love Body. this->retain(); @@ -529,7 +529,7 @@ int Body::setUserData(lua_State *L) if (udata == nullptr) { udata = new bodyudata(); - body->SetUserData(udata); + body->GetUserData().pointer = (uintptr_t)udata; } if(!udata->ref) diff --git a/src/modules/physics/box2d/Fixture.cpp b/src/modules/physics/box2d/Fixture.cpp index 6595eec1f..4d5c790ce 100644 --- a/src/modules/physics/box2d/Fixture.cpp +++ b/src/modules/physics/box2d/Fixture.cpp @@ -45,7 +45,7 @@ Fixture::Fixture(Body *body, Shape *shape, float density) udata->ref = nullptr; b2FixtureDef def; def.shape = shape->shape; - def.userData = udata; + def.userData.pointer = (uintptr_t)udata; def.density = density; fixture = body->body->CreateFixture(&def); this->retain(); @@ -262,7 +262,7 @@ int Fixture::setUserData(lua_State *L) if (udata == nullptr) { udata = new fixtureudata(); - fixture->SetUserData(udata); + fixture->GetUserData().pointer = (uintptr_t)udata; } if(!udata->ref) diff --git a/src/modules/physics/box2d/Joint.cpp b/src/modules/physics/box2d/Joint.cpp index a2e735fa3..ee5c46f2e 100644 --- a/src/modules/physics/box2d/Joint.cpp +++ b/src/modules/physics/box2d/Joint.cpp @@ -154,7 +154,7 @@ float Joint::getReactionTorque(float dt) b2Joint *Joint::createJoint(b2JointDef *def) { - def->userData = udata; + def->userData.pointer = (uintptr_t)udata; joint = world->world->CreateJoint(def); world->registerObject(joint, this); // Box2D joint has a reference to this love Joint. @@ -202,7 +202,7 @@ int Joint::setUserData(lua_State *L) if (udata == nullptr) { udata = new jointudata(); - joint->SetUserData(udata); + joint->GetUserData().pointer = (uintptr_t)udata; } if(!udata->ref) From dfd8c84d43409322be3ba6f7d92952e620e075d2 Mon Sep 17 00:00:00 2001 From: Garrett Brown Date: Sat, 17 Oct 2020 22:40:07 -0400 Subject: [PATCH 27/57] replace isfinite with std::isfinite --- src/libraries/box2d/b2_math.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/box2d/b2_math.h b/src/libraries/box2d/b2_math.h index 479e667be..64ce86f51 100644 --- a/src/libraries/box2d/b2_math.h +++ b/src/libraries/box2d/b2_math.h @@ -31,7 +31,7 @@ /// This function is used to ensure that a floating point number is not a NaN or infinity. inline bool b2IsValid(float x) { - return isfinite(x); + return std::isfinite(x); } #define b2Sqrt(x) sqrtf(x) From dd445ed1827a373dd38453de93228e19d9fb5ad8 Mon Sep 17 00:00:00 2001 From: Garrett Brown Date: Sat, 17 Oct 2020 22:52:58 -0400 Subject: [PATCH 28/57] Fix b2Assert location and fix isfinite missing --- src/libraries/box2d/b2_common.h | 3 ++- src/libraries/box2d/b2_math.h | 1 + src/libraries/box2d/b2_settings.h | 3 --- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libraries/box2d/b2_common.h b/src/libraries/box2d/b2_common.h index dfca8af1b..44d9a2625 100644 --- a/src/libraries/box2d/b2_common.h +++ b/src/libraries/box2d/b2_common.h @@ -34,7 +34,8 @@ #endif #define B2_NOT_USED(x) ((void)(x)) -#define b2Assert(A) assert(A) +void loveAssert(bool test, const char* teststr); +#define b2Assert(A) loveAssert((A), #A) #define b2_maxFloat FLT_MAX #define b2_epsilon FLT_EPSILON diff --git a/src/libraries/box2d/b2_math.h b/src/libraries/box2d/b2_math.h index 64ce86f51..cf90ad448 100644 --- a/src/libraries/box2d/b2_math.h +++ b/src/libraries/box2d/b2_math.h @@ -24,6 +24,7 @@ #define B2_MATH_H #include +#include #include "b2_api.h" #include "b2_settings.h" diff --git a/src/libraries/box2d/b2_settings.h b/src/libraries/box2d/b2_settings.h index 6db959ada..48cd95dfe 100644 --- a/src/libraries/box2d/b2_settings.h +++ b/src/libraries/box2d/b2_settings.h @@ -122,9 +122,6 @@ inline void b2Log(const char* string, ...) #endif // B2_USER_SETTINGS -void loveAssert(bool test, const char* teststr); -#define b2Assert(A) loveAssert((A), #A) - #include "b2_common.h" #endif From 7934ce0a66727e5ffe324a9c65e682c9b50a5617 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sun, 25 Oct 2020 22:24:07 -0300 Subject: [PATCH 29/57] Handle backbuffer MSAA manually in love.graphics code Previously love would use SDL APIs to make the system (WGL etc) handle it, which meant the OpenGL context had to be recreated whenever MSAA changed. --- src/modules/graphics/Graphics.h | 5 +- src/modules/graphics/opengl/Graphics.cpp | 169 ++++++++++++++++++----- src/modules/graphics/opengl/Graphics.h | 16 ++- src/modules/window/sdl/Window.cpp | 57 +++----- src/modules/window/sdl/Window.h | 4 +- 5 files changed, 175 insertions(+), 76 deletions(-) diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index d26ba929a..49a540aa5 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -471,7 +471,7 @@ public: * @param width The viewport width. * @param height The viewport height. **/ - virtual bool setMode(int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil) = 0; + virtual bool setMode(int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) = 0; /** * Un-sets the current graphics display mode (uninitializing objects if @@ -506,6 +506,9 @@ public: double getCurrentDPIScale() const; double getScreenDPIScale() const; + virtual int getRequestedBackbufferMSAA() const = 0; + virtual int getBackbufferMSAA() const = 0; + /** * Sets the current constant color. **/ diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index 8f6bfffb1..30bfa9ac5 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -91,6 +91,8 @@ static GLenum getGLBlendFactor(BlendFactor factor) Graphics::Graphics() : windowHasStencil(false) , mainVAO(0) + , internalBackbufferFBO(0) + , requestedBackbufferMSAA(0) , defaultBuffers() , supportedFormats() { @@ -105,14 +107,14 @@ Graphics::Graphics() if (window->isOpen()) { int w, h; - love::window::WindowSettings settings; - window->getWindow(w, h, settings); + love::window::WindowSettings s; + window->getWindow(w, h, s); double dpiW = w; double dpiH = h; window->windowToDPICoords(&dpiW, &dpiH); - setMode((int) dpiW, (int) dpiH, window->getPixelWidth(), window->getPixelHeight(), settings.stencil); + setMode((int) dpiW, (int) dpiH, window->getPixelWidth(), window->getPixelHeight(), s.stencil, s.msaa); } } } @@ -171,14 +173,94 @@ void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelh // Set up the projection matrix projectionMatrix = Matrix4::ortho(0.0, (float) width, (float) height, 0.0, -10.0f, 10.0f); } + + updateBackbuffer(width, height, pixelwidth, pixelheight, requestedBackbufferMSAA); } -bool Graphics::setMode(int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil) +void Graphics::updateBackbuffer(int width, int height, int /*pixelwidth*/, int pixelheight, int msaa) +{ + bool useinternalbackbuffer = false; + if (msaa > 1) + useinternalbackbuffer = true; + + // Our internal backbuffer code needs glBlitFramebuffer. + if (!(GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object || GLAD_ES_VERSION_3_0 + || GLAD_EXT_framebuffer_blit || GLAD_ANGLE_framebuffer_blit || GLAD_NV_framebuffer_blit)) + { + if (!(msaa > 1 && GLAD_APPLE_framebuffer_multisample)) + useinternalbackbuffer = false; + } + + GLuint prevFBO = gl.getFramebuffer(OpenGL::FRAMEBUFFER_ALL); + bool restoreFBO = prevFBO != getInternalBackbufferFBO(); + + if (useinternalbackbuffer) + { + Texture::Settings settings; + settings.width = width; + settings.height = height; + settings.dpiScale = (float)pixelheight / (float)height; + settings.msaa = msaa; + settings.renderTarget = true; + settings.readable.set(false); + + settings.format = isGammaCorrect() ? PIXELFORMAT_sRGBA8_UNORM : PIXELFORMAT_RGBA8_UNORM; + internalBackbuffer.set(newTexture(settings), Acquire::NORETAIN); + + settings.format = PIXELFORMAT_DEPTH24_UNORM_STENCIL8; + internalBackbufferDepthStencil.set(newTexture(settings), Acquire::NORETAIN); + + RenderTargets rts; + rts.colors.push_back(internalBackbuffer.get()); + rts.depthStencil.texture = internalBackbufferDepthStencil; + + internalBackbufferFBO = bindCachedFBO(rts); + } + else + { + internalBackbuffer.set(nullptr); + internalBackbufferDepthStencil.set(nullptr); + internalBackbufferFBO = 0; + } + + requestedBackbufferMSAA = msaa; + + if (restoreFBO) + gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, prevFBO); +} + +GLuint Graphics::getInternalBackbufferFBO() const +{ + if (internalBackbufferFBO != 0) + return internalBackbufferFBO; + else + return getSystemBackbufferFBO(); +} + +GLuint Graphics::getSystemBackbufferFBO() const +{ +#ifdef LOVE_IOS + // Hack: iOS uses a custom FBO. + SDL_SysWMinfo info = {}; + SDL_VERSION(&info.version); + SDL_GetWindowWMInfo(SDL_GL_GetCurrentWindow(), &info); + + if (info.info.uikit.resolveFramebuffer != 0) + return info.info.uikit.resolveFramebuffer; + else + return info.info.uikit.framebuffer; +#else + return 0; +#endif +} + +bool Graphics::setMode(int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) { this->width = width; this->height = height; this->windowHasStencil = windowhasstencil; + this->requestedBackbufferMSAA = msaa; // Okay, setup OpenGL. gl.initContext(); @@ -194,8 +276,6 @@ bool Graphics::setMode(int width, int height, int pixelwidth, int pixelheight, b created = true; initCapabilities(); - setViewportSize(width, height, pixelwidth, pixelheight); - // Enable blending gl.setEnableState(OpenGL::ENABLE_BLEND, true); @@ -235,6 +315,8 @@ bool Graphics::setMode(int width, int height, int pixelwidth, int pixelheight, b setDebug(isDebugEnabled()); + setViewportSize(width, height, pixelwidth, pixelheight); + if (batchedDrawState.vb[0] == nullptr) { // Initial sizes that should be good enough for most cases. It will @@ -318,6 +400,9 @@ void Graphics::unSetMode() flushBatchedDraws(); + internalBackbuffer.set(nullptr); + internalBackbufferDepthStencil.set(nullptr); + // Unload all volatile objects. These must be reloaded after the display // mode change. Volatile::unloadAll(); @@ -536,7 +621,7 @@ void Graphics::setRenderTargetsInternal(const RenderTargets &rts, int w, int h, if (iswindow) { - gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, gl.getDefaultFBO()); + gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, getInternalBackbufferFBO()); // The projection matrix is flipped compared to rendering to a texture, // due to OpenGL considering (0,0) bottom-left instead of top-left. @@ -578,6 +663,8 @@ void Graphics::endPass() // Discard the depth/stencil buffer if we're using an internal cached one. if (depthstencil == nullptr && (rts.temporaryRTFlags & (TEMPORARY_RT_DEPTH | TEMPORARY_RT_STENCIL)) != 0) discard({}, true); + else if (!rts.getFirstTarget().texture.get()) + discard({}, true); // Backbuffer // Resolve MSAA buffers. MSAA is only supported for 2D render targets so we // don't have to worry about resolving to slices. @@ -796,7 +883,7 @@ void Graphics::discard(OpenGL::FramebufferTarget target, const std::vector attachments.reserve(colorbuffers.size()); // glDiscardFramebuffer uses different attachment enums for the default FBO. - if (!isRenderTargetActive() && gl.getDefaultFBO() == 0) + if (!isRenderTargetActive() && getInternalBackbufferFBO() == 0) { if (colorbuffers.size() > 0 && colorbuffers[0]) attachments.push_back(GL_COLOR); @@ -863,7 +950,7 @@ void Graphics::cleanupRenderTexture(love::graphics::Texture *texture) } } -void Graphics::bindCachedFBO(const RenderTargets &targets) +GLuint Graphics::bindCachedFBO(const RenderTargets &targets) { GLuint fbo = framebufferObjects[targets]; @@ -946,6 +1033,8 @@ void Graphics::bindCachedFBO(const RenderTargets &targets) framebufferObjects[targets] = fbo; } + + return fbo; } void Graphics::present(void *screenshotCallbackData) @@ -961,13 +1050,34 @@ void Graphics::present(void *screenshotCallbackData) flushBatchedDraws(); endPass(); - gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, gl.getDefaultFBO()); + int w = getPixelWidth(); + int h = getPixelHeight(); + + gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, getInternalBackbufferFBO()); + + // Copy internal backbuffer to system backbuffer. When MSAA is used this + // is a direct MSAA resolve. + if (internalBackbuffer.get()) + { + gl.bindFramebuffer(OpenGL::FRAMEBUFFER_DRAW, getSystemBackbufferFBO()); + + // Discard system backbuffer to prevent it from copying its contents + // from VRAM to chip memory. + discard(OpenGL::FRAMEBUFFER_DRAW, {true}, true); + + // updateBackbuffer checks for glBlitFramebuffer support. + if (GLAD_APPLE_framebuffer_multisample && internalBackbuffer->getMSAA() > 1) + glResolveMultisampleFramebufferAPPLE(); + else + glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST); + + // Discarding the internal backbuffer directly after resolving it should + // eliminate any copy back to vram it might need to do. + discard(OpenGL::FRAMEBUFFER_READ, {true}, false); + } if (!pendingScreenshotCallbacks.empty()) { - int w = getPixelWidth(); - int h = getPixelHeight(); - size_t row = 4 * w; size_t size = row * h; @@ -986,26 +1096,7 @@ void Graphics::present(void *screenshotCallbackData) throw love::Exception("Out of memory."); } -#ifdef LOVE_IOS - SDL_SysWMinfo info = {}; - SDL_VERSION(&info.version); - SDL_GetWindowWMInfo(SDL_GL_GetCurrentWindow(), &info); - - if (info.info.uikit.resolveFramebuffer != 0) - { - gl.bindFramebuffer(OpenGL::FRAMEBUFFER_DRAW, info.info.uikit.resolveFramebuffer); - - // We need to do an explicit MSAA resolve on iOS, because it uses - // GLES FBOs rather than a system framebuffer. - if (GLAD_ES_VERSION_3_0) - glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST); - else if (GLAD_APPLE_framebuffer_multisample) - glResolveMultisampleFramebufferAPPLE(); - - gl.bindFramebuffer(OpenGL::FRAMEBUFFER_READ, info.info.uikit.resolveFramebuffer); - } -#endif - + gl.bindFramebuffer(OpenGL::FRAMEBUFFER_READ, getSystemBackbufferFBO()); glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels); // Replace alpha values with full opacity. @@ -1069,6 +1160,8 @@ void Graphics::present(void *screenshotCallbackData) if (window != nullptr) window->swapBuffers(); + gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, getInternalBackbufferFBO()); + // Reset the per-frame stat counts. drawCalls = 0; gl.stats.shaderSwitches = 0; @@ -1089,6 +1182,16 @@ void Graphics::present(void *screenshotCallbackData) } } +int Graphics::getRequestedBackbufferMSAA() const +{ + return requestedBackbufferMSAA; +} + +int Graphics::getBackbufferMSAA() const +{ + return internalBackbuffer.get() ? internalBackbuffer->getMSAA() : 0; +} + void Graphics::setScissor(const Rect &rect) { flushBatchedDraws(); diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index 62b0ae71f..40473327c 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -63,7 +63,7 @@ public: love::graphics::Buffer *newBuffer(const Buffer::Settings &settings, const std::vector &format, const void *data, size_t size, size_t arraylength) override; void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override; - bool setMode(int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil) override; + bool setMode(int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) override; void unSetMode() override; void setActive(bool active) override; @@ -79,6 +79,9 @@ public: void present(void *screenshotCallbackData) override; + int getRequestedBackbufferMSAA() const override; + int getBackbufferMSAA() const override; + void setColor(Colorf c) override; void setScissor(const Rect &rect) override; @@ -138,15 +141,24 @@ private: void getAPIStats(int &shaderswitches) const override; void endPass(); - void bindCachedFBO(const RenderTargets &targets); + GLuint bindCachedFBO(const RenderTargets &targets); void discard(OpenGL::FramebufferTarget target, const std::vector &colorbuffers, bool depthstencil); + void updateBackbuffer(int width, int height, int pixelwidth, int pixelheight, int msaa); + GLuint getInternalBackbufferFBO() const; + GLuint getSystemBackbufferFBO() const; + void setDebug(bool enable); std::unordered_map framebufferObjects; bool windowHasStencil; GLuint mainVAO; + StrongRef internalBackbuffer; + StrongRef internalBackbufferDepthStencil; + GLuint internalBackbufferFBO; + int requestedBackbufferMSAA; + // Only needed for buffer types that can be bound to shaders. StrongRef defaultBuffers[BUFFERTYPE_MAX_ENUM]; diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index 1f77ff641..f92241c7d 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -93,7 +93,7 @@ void Window::setGraphics(graphics::Graphics *graphics) this->graphics.set(graphics); } -void Window::setGLFramebufferAttributes(int msaa, bool sRGB, bool stencil, int depth) +void Window::setGLFramebufferAttributes(bool sRGB) { // Set GL window / framebuffer attributes. SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); @@ -101,12 +101,18 @@ void Window::setGLFramebufferAttributes(int msaa, bool sRGB, bool stencil, int d SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, stencil ? 8 : 0); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, depth); SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0); - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (msaa > 0) ? 1 : 0); - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, (msaa > 0) ? msaa : 0); + // Always use 24/8 depth/stencil (make sure any Graphics implementations + // that have their own backbuffer match this, too). + // Changing this after initial window creation would need the context to be + // destroyed and recreated, which we really don't want. + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + + // Backbuffer MSAA is handled by the love.graphics implementation. + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0); SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, sRGB ? 1 : 0); @@ -288,7 +294,7 @@ std::vector Window::getContextAttribsList() const return attribslist; } -bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowflags, int msaa, bool stencil, int depth) +bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowflags) { std::vector attribslist = getContextAttribsList(); @@ -350,10 +356,9 @@ bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowfla // Try each context profile in order. for (ContextAttribs attribs : attribslist) { - int curMSAA = msaa; bool curSRGB = love::graphics::isGammaCorrect(); - setGLFramebufferAttributes(curMSAA, curSRGB, stencil, depth); + setGLFramebufferAttributes(curSRGB); setGLContextAttributes(attribs); windowerror.clear(); @@ -361,33 +366,14 @@ bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowfla create(attribs); - if (!window && curMSAA > 0) - { - // The MSAA setting could have caused the failure. - setGLFramebufferAttributes(0, curSRGB, stencil, depth); - if (create(attribs)) - curMSAA = 0; - } - if (!window && curSRGB) { - // same with sRGB. - setGLFramebufferAttributes(curMSAA, false, stencil, depth); + // The sRGB setting could have caused the failure. + setGLFramebufferAttributes(false); if (create(attribs)) curSRGB = false; } - if (!window && curMSAA > 0 && curSRGB) - { - // Or both! - setGLFramebufferAttributes(0, false, stencil, depth); - if (create(attribs)) - { - curMSAA = 0; - curSRGB = false; - } - } - if (window && context) { // Store the successful context attributes so we can re-use them in @@ -515,7 +501,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings) close(); - if (!createWindowAndContext(x, y, width, height, sdlflags, f.msaa, f.stencil, f.depth)) + if (!createWindowAndContext(x, y, width, height, sdlflags)) return false; // Make sure the window keeps any previously set icon. @@ -540,7 +526,9 @@ bool Window::setWindow(int width, int height, WindowSettings *settings) { double scaledw, scaledh; fromPixels((double) pixelWidth, (double) pixelHeight, scaledw, scaledh); - graphics->setMode((int) scaledw, (int) scaledh, pixelWidth, pixelHeight, f.stencil); + graphics->setMode((int) scaledw, (int) scaledh, pixelWidth, pixelHeight, f.stencil, f.msaa); + + this->settings.msaa = graphics->getBackbufferMSAA(); } #ifdef LOVE_ANDROID @@ -617,13 +605,6 @@ void Window::updateSettings(const WindowSettings &newsettings, bool updateGraphi else SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0"); - // Verify MSAA setting. - int buffers = 0; - int samples = 0; - SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &buffers); - SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &samples); - - settings.msaa = (buffers > 0 ? samples : 0); settings.vsync = getVSync(); settings.stencil = newsettings.stencil; diff --git a/src/modules/window/sdl/Window.h b/src/modules/window/sdl/Window.h index e48a8bca8..7a56de991 100644 --- a/src/modules/window/sdl/Window.h +++ b/src/modules/window/sdl/Window.h @@ -139,11 +139,11 @@ private: bool debug; }; - void setGLFramebufferAttributes(int msaa, bool sRGB, bool stencil, int depth); + void setGLFramebufferAttributes(bool sRGB); void setGLContextAttributes(const ContextAttribs &attribs); bool checkGLVersion(const ContextAttribs &attribs, std::string &outversion); std::vector getContextAttribsList() const; - bool createWindowAndContext(int x, int y, int w, int h, Uint32 windowflags, int msaa, bool stencil, int depth); + bool createWindowAndContext(int x, int y, int w, int h, Uint32 windowflags); // Update the saved window settings based on the window's actual state. void updateSettings(const WindowSettings &newsettings, bool updateGraphicsViewport); From 442f37e0a1c50acdc9cff76d87ca5a1e6961f215 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sun, 25 Oct 2020 23:00:12 -0300 Subject: [PATCH 30/57] Fix a potential bug in captureScreenshot on some older systems --- src/modules/graphics/opengl/Graphics.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index 30bfa9ac5..463f88eb3 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -1096,7 +1096,7 @@ void Graphics::present(void *screenshotCallbackData) throw love::Exception("Out of memory."); } - gl.bindFramebuffer(OpenGL::FRAMEBUFFER_READ, getSystemBackbufferFBO()); + gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, getSystemBackbufferFBO()); glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels); // Replace alpha values with full opacity. From e10444c21f4e855ff69f0e2766399472fb7e7d0b Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sun, 25 Oct 2020 23:13:50 -0300 Subject: [PATCH 31/57] Move Texture:generateMipmaps error handling out of backend code --- src/modules/graphics/Texture.cpp | 17 ++++++++++++++++- src/modules/graphics/Texture.h | 7 +++++-- src/modules/graphics/opengl/Texture.cpp | 17 +++-------------- src/modules/graphics/opengl/Texture.h | 6 ++++-- 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/modules/graphics/Texture.cpp b/src/modules/graphics/Texture.cpp index 99b28e0ed..64d5faaa8 100644 --- a/src/modules/graphics/Texture.cpp +++ b/src/modules/graphics/Texture.cpp @@ -487,6 +487,17 @@ void Texture::replacePixels(const void *data, size_t size, int slice, int mipmap generateMipmaps(); } +void Texture::generateMipmaps() +{ + if (getMipmapCount() == 1 || getMipmapsMode() == MIPMAPS_NONE) + throw love::Exception("generateMipmaps can only be called on a Texture which was created with mipmaps enabled."); + + if (isPixelFormatCompressed(format)) + throw love::Exception("generateMipmaps cannot be called on a compressed Texture."); + + generateMipmapsInternal(); +} + love::image::ImageData *Texture::newImageData(love::image::Image *module, int slice, int mipmap, const Rect &r) { if (!isReadable()) @@ -521,7 +532,11 @@ love::image::ImageData *Texture::newImageData(love::image::Image *module, int sl throw love::Exception("ImageData with the '%s' pixel format is not supported.", formatname); } - return module->newImageData(r.w, r.h, dataformat); + auto imagedata = module->newImageData(r.w, r.h, dataformat); + + readbackImageData(imagedata, slice, mipmap, r); + + return imagedata; } TextureType Texture::getTextureType() const diff --git a/src/modules/graphics/Texture.h b/src/modules/graphics/Texture.h index 1f4e52671..c6ee1b01b 100644 --- a/src/modules/graphics/Texture.h +++ b/src/modules/graphics/Texture.h @@ -218,9 +218,9 @@ public: void replacePixels(love::image::ImageDataBase *d, int slice, int mipmap, int x, int y, bool reloadmipmaps); void replacePixels(const void *data, size_t size, int slice, int mipmap, const Rect &rect, bool reloadmipmaps); - virtual void generateMipmaps() = 0; + void generateMipmaps(); - virtual love::image::ImageData *newImageData(love::image::Image *module, int slice, int mipmap, const Rect &rect); + love::image::ImageData *newImageData(love::image::Image *module, int slice, int mipmap, const Rect &rect); virtual ptrdiff_t getRenderTargetHandle() const = 0; @@ -278,6 +278,9 @@ protected: void uploadImageData(love::image::ImageDataBase *d, int level, int slice, int x, int y); virtual void uploadByteData(PixelFormat pixelformat, const void *data, size_t size, int level, int slice, const Rect &r, love::image::ImageDataBase *imgd = nullptr) = 0; + virtual void generateMipmapsInternal() = 0; + virtual void readbackImageData(love::image::ImageData *imagedata, int slice, int mipmap, const Rect &rect) = 0; + bool validateDimensions(bool throwException) const; TextureType texType; diff --git a/src/modules/graphics/opengl/Texture.cpp b/src/modules/graphics/opengl/Texture.cpp index b51cfbdfb..72f1c684f 100644 --- a/src/modules/graphics/opengl/Texture.cpp +++ b/src/modules/graphics/opengl/Texture.cpp @@ -480,14 +480,8 @@ void Texture::uploadByteData(PixelFormat pixelformat, const void *data, size_t s } } -void Texture::generateMipmaps() +void Texture::generateMipmapsInternal() { - if (getMipmapCount() == 1 || getMipmapsMode() == MIPMAPS_NONE) - throw love::Exception("generateMipmaps can only be called on a Texture which was created with mipmaps enabled."); - - if (isPixelFormatCompressed(format)) - throw love::Exception("generateMipmaps cannot be called on a compressed Texture."); - gl.bindTextureToUnit(this, 0, false); GLenum gltextype = OpenGL::getGLTextureType(texType); @@ -498,13 +492,10 @@ void Texture::generateMipmaps() glGenerateMipmap(gltextype); } -love::image::ImageData *Texture::newImageData(love::image::Image *module, int slice, int mipmap, const Rect &r) +void Texture::readbackImageData(love::image::ImageData *data, int slice, int mipmap, const Rect &r) { - // Base class does validation (only RTs allowed, etc) and creates ImageData. - love::image::ImageData *data = love::graphics::Texture::newImageData(module, slice, mipmap, r); - if (fbo == 0) // Should never be reached. - return data; + return; bool isSRGB = false; OpenGL::TextureFormat fmt = gl.convertPixelFormat(data->getFormat(), false, isSRGB); @@ -525,8 +516,6 @@ love::image::ImageData *Texture::newImageData(love::image::Image *module, int sl gl.framebufferTexture(GL_COLOR_ATTACHMENT0, texType, texture, 0, 0, 0); gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, current_fbo); - - return data; } void Texture::setSamplerState(const SamplerState &s) diff --git a/src/modules/graphics/opengl/Texture.h b/src/modules/graphics/opengl/Texture.h index 4f0d871d3..9619a8a1c 100644 --- a/src/modules/graphics/opengl/Texture.h +++ b/src/modules/graphics/opengl/Texture.h @@ -46,8 +46,6 @@ public: bool loadVolatile() override; void unloadVolatile() override; - void generateMipmaps() override; - love::image::ImageData *newImageData(love::image::Image *module, int slice, int mipmap, const Rect &rect) override; void setSamplerState(const SamplerState &s) override; ptrdiff_t getHandle() const override; @@ -62,6 +60,10 @@ private: void uploadByteData(PixelFormat pixelformat, const void *data, size_t size, int level, int slice, const Rect &r, love::image::ImageDataBase *imgd = nullptr) override; + void generateMipmapsInternal() override; + + void readbackImageData(love::image::ImageData *imagedata, int slice, int mipmap, const Rect &rect) override; + Slices slices; GLuint fbo; From 99875d83b3612bc2cbbef631b7e7651ba6f4852a Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Mon, 26 Oct 2020 17:11:50 -0300 Subject: [PATCH 32/57] Fix explicit texture MSAA of 1 or 0 not being treated the same as the default --- src/modules/graphics/Texture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/graphics/Texture.cpp b/src/modules/graphics/Texture.cpp index 64d5faaa8..6f02cb36f 100644 --- a/src/modules/graphics/Texture.cpp +++ b/src/modules/graphics/Texture.cpp @@ -173,7 +173,7 @@ Texture::Texture(const Settings &settings, const Slices *slices) , mipmapCount(1) , pixelWidth(0) , pixelHeight(0) - , requestedMSAA(settings.msaa) + , requestedMSAA(settings.msaa > 1 ? settings.msaa : 0) , samplerState() , graphicsMemorySize(0) , usingDefaultTexture(false) From 7e0c7e3a6703a05b78853830b7cf5f277ed81ae4 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Mon, 26 Oct 2020 18:25:40 -0300 Subject: [PATCH 33/57] Fix the default mipmap filter for textures. --- src/modules/graphics/Graphics.cpp | 5 +++++ src/modules/graphics/Graphics.h | 3 +++ src/modules/graphics/Texture.cpp | 3 +++ 3 files changed, 11 insertions(+) diff --git a/src/modules/graphics/Graphics.cpp b/src/modules/graphics/Graphics.cpp index 001806e85..7a985eed7 100644 --- a/src/modules/graphics/Graphics.cpp +++ b/src/modules/graphics/Graphics.cpp @@ -104,6 +104,11 @@ bool isDebugEnabled() love::Type Graphics::type("graphics", &Module::type); +Graphics::DisplayState::DisplayState() +{ + defaultSamplerState.mipmapFilter = SamplerState::MIPMAP_FILTER_LINEAR; +} + Graphics::Graphics() : width(0) , height(0) diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index 49a540aa5..0ad0c5528 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -869,6 +869,8 @@ protected: struct DisplayState { + DisplayState(); + Colorf color = Colorf(1.0, 1.0, 1.0, 1.0); Colorf backgroundColor = Colorf(0.0, 0.0, 0.0, 1.0); @@ -901,6 +903,7 @@ protected: bool wireframe = false; + // Default mipmap filter is set in the DisplayState constructor. SamplerState defaultSamplerState = SamplerState(); }; diff --git a/src/modules/graphics/Texture.cpp b/src/modules/graphics/Texture.cpp index 6f02cb36f..8897b8de7 100644 --- a/src/modules/graphics/Texture.cpp +++ b/src/modules/graphics/Texture.cpp @@ -281,6 +281,9 @@ Texture::Texture(const Settings &settings, const Slices *slices) samplerState = gfx->getDefaultSamplerState(); + if (getMipmapCount() == 1) + samplerState.mipmapFilter = SamplerState::MIPMAP_FILTER_NONE; + Quad::Viewport v = {0, 0, (double) width, (double) height}; quad.set(new Quad(v, width, height), Acquire::NORETAIN); From f519d2e2dfacbbcfaf1365317efbfe970874c423 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Mon, 26 Oct 2020 20:37:41 -0300 Subject: [PATCH 34/57] macOS: fix issues with drag-and-drop to open a love game - Fix love.event.quit("restart") running the no-game screen instead of the current game. - Fix fused apps opening other games when drag-and-drop is used. --- src/love.cpp | 53 ++++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/src/love.cpp b/src/love.cpp index 414472eda..5dbc9b134 100644 --- a/src/love.cpp +++ b/src/love.cpp @@ -75,38 +75,39 @@ static void get_app_arguments(int argc, char **argv, int &new_argc, char **&new_ temp_argv.push_back(std::string(argv[i])); } -#ifdef LOVE_MACOSX - // Check for a drop file string, if the app wasn't launched in a terminal. - // Checking for the terminal is a pretty big hack, but works around an issue - // where OS X will switch Spaces if the terminal launching love is in its - // own full-screen Space. - std::string dropfilestr; - if (!isatty(STDIN_FILENO)) - dropfilestr = love::macosx::checkDropEvents(); - - if (!dropfilestr.empty()) - temp_argv.insert(temp_argv.begin() + 1, dropfilestr); - else -#endif - { - // If it exists, add the love file in love.app/Contents/Resources/ to argv. - std::string loveResourcesPath; - bool fused = true; + // If it exists, add the love file in love.app/Contents/Resources/ to argv. + std::string loveResourcesPath; + bool fused = true; #if defined(LOVE_MACOSX) - loveResourcesPath = love::macosx::getLoveInResources(); + loveResourcesPath = love::macosx::getLoveInResources(); #elif defined(LOVE_IOS) - loveResourcesPath = love::ios::getLoveInResources(fused); + loveResourcesPath = love::ios::getLoveInResources(fused); #endif - if (!loveResourcesPath.empty()) - { - std::vector::iterator it = temp_argv.begin(); - it = temp_argv.insert(it + 1, loveResourcesPath); + if (!loveResourcesPath.empty()) + { + std::vector::iterator it = temp_argv.begin(); + it = temp_argv.insert(it + 1, loveResourcesPath); - // Run in pseudo-fused mode. - if (fused) - temp_argv.insert(it + 1, std::string("--fused")); + // Run in pseudo-fused mode. + if (fused) + temp_argv.insert(it + 1, std::string("--fused")); + } +#ifdef LOVE_MACOSX + else + { + // Check for a drop file string, if the app wasn't launched in a + // terminal. Checking for the terminal is a pretty big hack, but works + // around an issue where OS X will switch Spaces if the terminal + // launching love is in its own full-screen Space. + if (!isatty(STDIN_FILENO)) + { + // Static to keep the same value after love.event.equit("restart"). + static std::string dropfilestr = love::macosx::checkDropEvents(); + if (!dropfilestr.empty()) + temp_argv.insert(temp_argv.begin() + 1, dropfilestr); } } +#endif // Copy temp argv vector to new argv array. new_argc = (int) temp_argv.size(); From 905e5baf06145bb92214d59cd3f5a25a0bb57c4c Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sun, 1 Nov 2020 21:36:15 -0400 Subject: [PATCH 35/57] Replace highdpi window flag with t.highdpi in love.conf --- src/modules/love/love.cpp | 16 ++++++++++++++++ src/modules/window/Window.cpp | 12 ++++++++++++ src/modules/window/Window.h | 7 +++++-- src/modules/window/sdl/Window.cpp | 5 +++-- src/modules/window/wrap_Window.cpp | 22 ++++++++++++++++++---- src/scripts/boot.lua | 8 ++++++-- src/scripts/boot.lua.h | 12 +++++++++--- src/scripts/nogame.lua | 2 +- src/scripts/nogame.lua.h | 3 +-- 9 files changed, 71 insertions(+), 16 deletions(-) diff --git a/src/modules/love/love.cpp b/src/modules/love/love.cpp index 475f557da..8cc02f9bb 100644 --- a/src/modules/love/love.cpp +++ b/src/modules/love/love.cpp @@ -65,6 +65,11 @@ # include "graphics/Graphics.h" #endif +// For love::window::setHighDPIAllowed +#ifdef LOVE_ENABLE_WINDOW +# include "window/Window.h" +#endif + // For love::audio::Audio::setMixWithSystem. #ifdef LOVE_ENABLE_AUDIO # include "audio/Audio.h" @@ -318,6 +323,14 @@ static int w__setGammaCorrect(lua_State *L) return 0; } +static int w__setHighDPIAllowed(lua_State *L) +{ +#ifdef LOVE_ENABLE_WINDOW + love::window::setHighDPIAllowed((bool) lua_toboolean(L, 1)); +#endif + return 0; +} + static int w__setAudioMixWithSystem(lua_State *L) { bool success = false; @@ -395,6 +408,9 @@ int luaopen_love(lua_State *L) lua_pushcfunction(L, w__setGammaCorrect); lua_setfield(L, -2, "_setGammaCorrect"); + lua_pushcfunction(L, w__setHighDPIAllowed); + lua_setfield(L, -2, "_setHighDPIAllowed"); + // Exposed here because we need to be able to call it before the audio // module is initialized. lua_pushcfunction(L, w__setAudioMixWithSystem); diff --git a/src/modules/window/Window.cpp b/src/modules/window/Window.cpp index 84f1172b2..804b74fa1 100644 --- a/src/modules/window/Window.cpp +++ b/src/modules/window/Window.cpp @@ -26,6 +26,18 @@ namespace love namespace window { +static bool highDPIAllowed = false; + +void setHighDPIAllowed(bool enable) +{ + highDPIAllowed = enable; +} + +bool isHighDPIAllowed() +{ + return highDPIAllowed; +} + Window::~Window() { } diff --git a/src/modules/window/Window.h b/src/modules/window/Window.h index cf7a70921..6cdacf92f 100644 --- a/src/modules/window/Window.h +++ b/src/modules/window/Window.h @@ -43,6 +43,10 @@ class Graphics; namespace window { +// Applied when the window is first created. +void setHighDPIAllowed(bool enable); +bool isHighDPIAllowed(); + // Forward-declared so it can be used in the class methods. We can't define the // whole thing here because it uses the Window::Type enum. struct WindowSettings; @@ -66,7 +70,7 @@ public: SETTING_BORDERLESS, SETTING_CENTERED, SETTING_DISPLAY, - SETTING_HIGHDPI, + SETTING_HIGHDPI, // Deprecated SETTING_USE_DPISCALE, SETTING_REFRESHRATE, SETTING_X, @@ -261,7 +265,6 @@ struct WindowSettings bool borderless = false; bool centered = true; int display = 0; - bool highdpi = false; bool usedpiscale = true; double refreshrate = 0.0; bool useposition = false; diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index f92241c7d..84128ceaf 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -477,7 +477,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings) if (f.borderless) sdlflags |= SDL_WINDOW_BORDERLESS; - if (f.highdpi) + if (isHighDPIAllowed()) sdlflags |= SDL_WINDOW_ALLOW_HIGHDPI; int x = f.x; @@ -596,7 +596,8 @@ void Window::updateSettings(const WindowSettings &newsettings, bool updateGraphi getPosition(settings.x, settings.y, settings.display); - settings.highdpi = (wflags & SDL_WINDOW_ALLOW_HIGHDPI) != 0; + setHighDPIAllowed((wflags & SDL_WINDOW_ALLOW_HIGHDPI) != 0); + settings.usedpiscale = newsettings.usedpiscale; // Only minimize on focus loss if the window is in exclusive-fullscreen mode diff --git a/src/modules/window/wrap_Window.cpp b/src/modules/window/wrap_Window.cpp index ce2f830b6..36d061681 100644 --- a/src/modules/window/wrap_Window.cpp +++ b/src/modules/window/wrap_Window.cpp @@ -75,9 +75,19 @@ static int readWindowSettings(lua_State *L, int idx, WindowSettings &settings) settings.borderless = luax_boolflag(L, idx, settingName(Window::SETTING_BORDERLESS), settings.borderless); settings.centered = luax_boolflag(L, idx, settingName(Window::SETTING_CENTERED), settings.centered); settings.display = luax_intflag(L, idx, settingName(Window::SETTING_DISPLAY), settings.display+1) - 1; - settings.highdpi = luax_boolflag(L, idx, settingName(Window::SETTING_HIGHDPI), settings.highdpi); settings.usedpiscale = luax_boolflag(L, idx, settingName(Window::SETTING_USE_DPISCALE), settings.usedpiscale); + lua_getfield(L, idx, settingName(Window::SETTING_HIGHDPI)); + if (!lua_isnoneornil(L, -1)) + { + luax_markdeprecated(L, "window.highdpi", API_FIELD, DEPRECATED_REPLACED, "t.highdpi in love.conf"); + bool highdpi = luax_checkboolean(L, -1); + if (!instance()->isOpen()) + setHighDPIAllowed(highdpi); + + } + lua_pop(L, 1); + lua_getfield(L, idx, settingName(Window::SETTING_VSYNC)); if (lua_isnumber(L, -1)) settings.vsync = (int) lua_tointeger(L, -1); @@ -201,9 +211,6 @@ int w_getMode(lua_State *L) lua_pushinteger(L, settings.display + 1); lua_setfield(L, -2, settingName(Window::SETTING_DISPLAY)); - luax_pushboolean(L, settings.highdpi); - lua_setfield(L, -2, settingName(Window::SETTING_HIGHDPI)); - luax_pushboolean(L, settings.usedpiscale); lua_setfield(L, -2, settingName(Window::SETTING_USE_DPISCALE)); @@ -219,6 +226,12 @@ int w_getMode(lua_State *L) return 3; } +int w_isHighDPIAllowed(lua_State *L) +{ + luax_pushboolean(L, isHighDPIAllowed()); + return 1; +} + int w_getDisplayOrientation(lua_State *L) { int displayindex = 0; @@ -618,6 +631,7 @@ static const luaL_Reg functions[] = { "setMode", w_setMode }, { "updateMode", w_updateMode }, { "getMode", w_getMode }, + { "isHighDPIAllowed", w_isHighDPIAllowed }, { "getDisplayOrientation", w_getDisplayOrientation }, { "getFullscreenModes", w_getFullscreenModes }, { "setFullscreen", w_setFullscreen }, diff --git a/src/scripts/boot.lua b/src/scripts/boot.lua index 2d491910a..03db5c89e 100644 --- a/src/scripts/boot.lua +++ b/src/scripts/boot.lua @@ -400,7 +400,6 @@ function love.init() borderless = false, resizable = false, centered = true, - highdpi = false, usedpiscale = true, }, modules = { @@ -433,6 +432,7 @@ function love.init() externalstorage = false, -- Only relevant for Android. accelerometerjoystick = true, -- Only relevant for Android / iOS. gammacorrect = false, + highdpi = false, } -- Console hack, part 1. @@ -470,6 +470,10 @@ function love.init() love._setGammaCorrect(c.gammacorrect) end + if love._setHighDPIAllowed then + love._setHighDPIAllowed(c.highdpi) + end + if love._setAudioMixWithSystem then if c.audio and c.audio.mixwithsystem ~= nil then love._setAudioMixWithSystem(c.audio.mixwithsystem) @@ -547,7 +551,7 @@ function love.init() borderless = c.window.borderless, centered = c.window.centered, display = c.window.display, - highdpi = c.window.highdpi, + highdpi = c.window.highdpi, -- deprecated usedpiscale = c.window.usedpiscale, x = c.window.x, y = c.window.y, diff --git a/src/scripts/boot.lua.h b/src/scripts/boot.lua.h index 850713995..8f2e59066 100644 --- a/src/scripts/boot.lua.h +++ b/src/scripts/boot.lua.h @@ -808,8 +808,6 @@ const unsigned char boot_lua[] = 0x73, 0x65, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a, - 0x09, 0x09, 0x09, 0x68, 0x69, 0x67, 0x68, 0x64, 0x70, 0x69, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, - 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x75, 0x73, 0x65, 0x64, 0x70, 0x69, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a, 0x09, 0x09, 0x7d, 0x2c, 0x0a, @@ -862,6 +860,7 @@ const unsigned char boot_lua[] = 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x20, 0x2f, 0x20, 0x69, 0x4f, 0x53, 0x2e, 0x0a, 0x09, 0x09, 0x67, 0x61, 0x6d, 0x6d, 0x61, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x0a, + 0x09, 0x09, 0x68, 0x69, 0x67, 0x68, 0x64, 0x70, 0x69, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x0a, 0x09, 0x7d, 0x0a, 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x20, 0x68, 0x61, 0x63, 0x6b, 0x2c, 0x20, @@ -946,6 +945,12 @@ const unsigned char boot_lua[] = 0x63, 0x74, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x73, 0x65, 0x74, 0x48, 0x69, 0x67, 0x68, 0x44, + 0x50, 0x49, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x73, 0x65, 0x74, 0x48, 0x69, 0x67, 0x68, 0x44, 0x50, 0x49, + 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x28, 0x63, 0x2e, 0x68, 0x69, 0x67, 0x68, 0x64, 0x70, 0x69, 0x29, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x73, 0x65, 0x74, 0x41, 0x75, 0x64, 0x69, 0x6f, 0x4d, 0x69, 0x78, 0x57, 0x69, 0x74, 0x68, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x63, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, @@ -1089,7 +1094,8 @@ const unsigned char boot_lua[] = 0x09, 0x09, 0x09, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x68, 0x69, 0x67, 0x68, 0x64, 0x70, 0x69, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, - 0x64, 0x6f, 0x77, 0x2e, 0x68, 0x69, 0x67, 0x68, 0x64, 0x70, 0x69, 0x2c, 0x0a, + 0x64, 0x6f, 0x77, 0x2e, 0x68, 0x69, 0x67, 0x68, 0x64, 0x70, 0x69, 0x2c, 0x20, 0x2d, 0x2d, 0x20, 0x64, 0x65, + 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x0a, 0x09, 0x09, 0x09, 0x75, 0x73, 0x65, 0x64, 0x70, 0x69, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x75, 0x73, 0x65, 0x64, 0x70, 0x69, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2c, 0x0a, diff --git a/src/scripts/nogame.lua b/src/scripts/nogame.lua index f9603b9eb..3380dcc01 100644 --- a/src/scripts/nogame.lua +++ b/src/scripts/nogame.lua @@ -3274,7 +3274,7 @@ function love.nogame() t.modules.sound = false t.modules.joystick = false t.window.resizable = true - t.window.highdpi = true + t.highdpi = true if love._os == "iOS" then t.window.borderless = true diff --git a/src/scripts/nogame.lua.h b/src/scripts/nogame.lua.h index d3e51767f..acf149c7c 100644 --- a/src/scripts/nogame.lua.h +++ b/src/scripts/nogame.lua.h @@ -12115,8 +12115,7 @@ const unsigned char nogame_lua[] = 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x74, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, - 0x09, 0x09, 0x74, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x68, 0x69, 0x67, 0x68, 0x64, 0x70, 0x69, - 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, + 0x09, 0x09, 0x74, 0x2e, 0x68, 0x69, 0x67, 0x68, 0x64, 0x70, 0x69, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x6f, 0x73, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x69, 0x4f, 0x53, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, From 23a03416762410e5770838cd5695adf17c0a514f Mon Sep 17 00:00:00 2001 From: Garrett Brown Date: Sun, 1 Nov 2020 22:46:31 -0500 Subject: [PATCH 36/57] Fix missing loveAssert --- src/libraries/box2d/common/b2_settings.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libraries/box2d/common/b2_settings.cpp b/src/libraries/box2d/common/b2_settings.cpp index 9b66769ac..5ee213ef2 100644 --- a/src/libraries/box2d/common/b2_settings.cpp +++ b/src/libraries/box2d/common/b2_settings.cpp @@ -27,6 +27,8 @@ #include #include +#include "common/Exception.h" + b2Version b2_version = {2, 4, 0}; // Memory allocators. Modify these to use your own allocator. @@ -46,6 +48,12 @@ void b2Log_Default(const char* string, va_list args) vprintf(string, args); } +void loveAssert(bool test, const char* teststr) +{ + if (!test) + throw love::Exception("Box2D assertion failed: %s", teststr); +} + FILE* b2_dumpFile = nullptr; void b2OpenDump(const char* fileName) From 316fccfe1b6058ddd0a668b6a6bf2d42905cfa1e Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Mon, 2 Nov 2020 18:08:35 -0400 Subject: [PATCH 37/57] love.window.setMode no longer destroys and recreates the window --- src/modules/window/sdl/Window.cpp | 120 +++++++++++++++++++----------- src/modules/window/sdl/Window.h | 4 +- 2 files changed, 79 insertions(+), 45 deletions(-) diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index 84128ceaf..3abf1e33e 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -421,6 +421,9 @@ bool Window::setWindow(int width, int height, WindowSettings *settings) if (graphics.get() && graphics->isRenderTargetActive()) throw love::Exception("love.window.setMode cannot be called while a render target is active in love.graphics."); + if (isOpen()) + updateSettings(this->settings, false); + WindowSettings f; if (settings) @@ -440,46 +443,11 @@ bool Window::setWindow(int width, int height, WindowSettings *settings) height = mode.h; } - Uint32 sdlflags = SDL_WINDOW_OPENGL; - // On Android we always must have fullscreen type FULLSCREEN_TYPE_DESKTOP #ifdef LOVE_ANDROID f.fstype = FULLSCREEN_DESKTOP; #endif - if (f.fullscreen) - { - if (f.fstype == FULLSCREEN_DESKTOP) - sdlflags |= SDL_WINDOW_FULLSCREEN_DESKTOP; - else - { - sdlflags |= SDL_WINDOW_FULLSCREEN; - SDL_DisplayMode mode = {0, width, height, 0, nullptr}; - - // Fullscreen window creation will bug out if no mode can be used. - if (SDL_GetClosestDisplayMode(f.display, &mode, &mode) == nullptr) - { - // GetClosestDisplayMode will fail if we request a size larger - // than the largest available display mode, so we'll try to use - // the largest (first) mode in that case. - if (SDL_GetDisplayMode(f.display, 0, &mode) < 0) - return false; - } - - width = mode.w; - height = mode.h; - } - } - - if (f.resizable) - sdlflags |= SDL_WINDOW_RESIZABLE; - - if (f.borderless) - sdlflags |= SDL_WINDOW_BORDERLESS; - - if (isHighDPIAllowed()) - sdlflags |= SDL_WINDOW_ALLOW_HIGHDPI; - int x = f.x; int y = f.y; @@ -499,10 +467,68 @@ bool Window::setWindow(int width, int height, WindowSettings *settings) x = y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(f.display); } - close(); + SDL_DisplayMode fsmode = {0, width, height, 0, nullptr}; - if (!createWindowAndContext(x, y, width, height, sdlflags)) - return false; + if (f.fullscreen && f.fstype == FULLSCREEN_EXCLUSIVE) + { + // Fullscreen window creation will bug out if no mode can be used. + if (SDL_GetClosestDisplayMode(f.display, &fsmode, &fsmode) == nullptr) + { + // GetClosestDisplayMode will fail if we request a size larger + // than the largest available display mode, so we'll try to use + // the largest (first) mode in that case. + if (SDL_GetDisplayMode(f.display, 0, &fsmode) < 0) + return false; + } + } + + bool needsetmode = false; + + Uint32 sdlflags = 0; + + if (f.fullscreen) + { + if (f.fstype == FULLSCREEN_DESKTOP) + sdlflags |= SDL_WINDOW_FULLSCREEN_DESKTOP; + else + { + sdlflags |= SDL_WINDOW_FULLSCREEN; + width = fsmode.w; + height = fsmode.h; + } + } + + if (isOpen()) + { + if (SDL_SetWindowFullscreen(window, sdlflags) == 0) + SDL_GL_MakeCurrent(window, context); + + if (!f.fullscreen) + SDL_SetWindowSize(window, width, height); + + if (this->settings.resizable != f.resizable) + SDL_SetWindowResizable(window, f.resizable ? SDL_TRUE : SDL_FALSE); + if (this->settings.borderless != f.borderless) + SDL_SetWindowBordered(window, f.borderless ? SDL_FALSE : SDL_TRUE); + } + else + { + sdlflags |= SDL_WINDOW_OPENGL; + + if (f.resizable) + sdlflags |= SDL_WINDOW_RESIZABLE; + + if (f.borderless) + sdlflags |= SDL_WINDOW_BORDERLESS; + + if (isHighDPIAllowed()) + sdlflags |= SDL_WINDOW_ALLOW_HIGHDPI; + + if (!createWindowAndContext(x, y, width, height, sdlflags)) + return false; + + needsetmode = true; + } // Make sure the window keeps any previously set icon. setIcon(icon.get()); @@ -513,7 +539,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings) // Enforce minimum window dimensions. SDL_SetWindowMinimumSize(window, f.minwidth, f.minheight); - if ((f.useposition || f.centered) && !f.fullscreen) + if (this->settings.display != f.display || ((f.useposition || f.centered) && !f.fullscreen)) SDL_SetWindowPosition(window, x, y); SDL_RaiseWindow(window); @@ -526,9 +552,16 @@ bool Window::setWindow(int width, int height, WindowSettings *settings) { double scaledw, scaledh; fromPixels((double) pixelWidth, (double) pixelHeight, scaledw, scaledh); - graphics->setMode((int) scaledw, (int) scaledh, pixelWidth, pixelHeight, f.stencil, f.msaa); - this->settings.msaa = graphics->getBackbufferMSAA(); + if (needsetmode) + { + graphics->setMode((int) scaledw, (int) scaledh, pixelWidth, pixelHeight, f.stencil, f.msaa); + this->settings.msaa = graphics->getBackbufferMSAA(); + } + else + { + graphics->setViewportSize((int) scaledw, (int) scaledh, pixelWidth, pixelHeight); + } } #ifdef LOVE_ANDROID @@ -671,7 +704,7 @@ void Window::close(bool allowExceptions) open = false; } -bool Window::setFullscreen(bool fullscreen, Window::FullscreenType fstype) +bool Window::setFullscreen(bool fullscreen, FullscreenType fstype) { if (!window) return false; @@ -709,9 +742,10 @@ bool Window::setFullscreen(bool fullscreen, Window::FullscreenType fstype) if (SDL_SetWindowFullscreen(window, sdlflags) == 0) { SDL_GL_MakeCurrent(window, context); + updateSettings(newsettings, true); - // Apparently this gets un-set when we exit fullscreen (at least in OS X). + // This gets un-set when we exit fullscreen (at least in macOS). if (!fullscreen) SDL_SetWindowMinimumSize(window, settings.minwidth, settings.minheight); diff --git a/src/modules/window/sdl/Window.h b/src/modules/window/sdl/Window.h index 7a56de991..0912d8454 100644 --- a/src/modules/window/sdl/Window.h +++ b/src/modules/window/sdl/Window.h @@ -129,8 +129,6 @@ public: private: - void close(bool allowExceptions); - struct ContextAttribs { int versionMajor; @@ -139,6 +137,8 @@ private: bool debug; }; + void close(bool allowExceptions); + void setGLFramebufferAttributes(bool sRGB); void setGLContextAttributes(const ContextAttribs &attribs); bool checkGLVersion(const ContextAttribs &attribs, std::string &outversion); From 5031cb5f56ad9c1946caaa43c98b42d04a8ff552 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Mon, 2 Nov 2020 18:17:07 -0400 Subject: [PATCH 38/57] Images don't hold on to RAM copies of their contents anymore --- src/modules/graphics/opengl/Texture.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/modules/graphics/opengl/Texture.cpp b/src/modules/graphics/opengl/Texture.cpp index 72f1c684f..669753404 100644 --- a/src/modules/graphics/opengl/Texture.cpp +++ b/src/modules/graphics/opengl/Texture.cpp @@ -218,6 +218,10 @@ Texture::Texture(const Settings &settings, const Slices *data) if (textureGLError != GL_NO_ERROR) throw love::Exception("Cannot create Texture (OpenGL error: %s)", OpenGL::errorString(textureGLError)); } + + // ImageData is referenced by the first loadVolatile call, but we don't + // hang on to it after that so we can save memory. + slices.clear(); } Texture::~Texture() From 3d2614ff2ee284c516c6b24466d945e1d0640cee Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Mon, 2 Nov 2020 18:20:58 -0400 Subject: [PATCH 39/57] Fix compilation when SDL < 2.0.5 is used --- src/modules/window/sdl/Window.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index 3abf1e33e..5bad632be 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -506,8 +506,13 @@ bool Window::setWindow(int width, int height, WindowSettings *settings) if (!f.fullscreen) SDL_SetWindowSize(window, width, height); + // On linux systems 2.0.5+ might not be available... + // TODO: require at least 2.0.5? +#if SDL_VERSION_ATLEAST(2, 0, 5) if (this->settings.resizable != f.resizable) SDL_SetWindowResizable(window, f.resizable ? SDL_TRUE : SDL_FALSE); +#endif + if (this->settings.borderless != f.borderless) SDL_SetWindowBordered(window, f.borderless ? SDL_FALSE : SDL_TRUE); } From c12b46da98f8b8a8e98517ff29e6ea21740f2e26 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Tue, 3 Nov 2020 22:11:07 -0400 Subject: [PATCH 40/57] Fix compilation on macOS/iOS after box2d update --- .../xcode/liblove.xcodeproj/project.pbxproj | 1048 ++++++++--------- src/libraries/box2d/dynamics/b2_island.cpp | 2 +- 2 files changed, 521 insertions(+), 529 deletions(-) diff --git a/platform/xcode/liblove.xcodeproj/project.pbxproj b/platform/xcode/liblove.xcodeproj/project.pbxproj index 953bc1722..07c676ba9 100644 --- a/platform/xcode/liblove.xcodeproj/project.pbxproj +++ b/platform/xcode/liblove.xcodeproj/project.pbxproj @@ -108,145 +108,6 @@ FA0B79471A958E3B000E1D17 /* Vector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79161A958E3B000E1D17 /* Vector.cpp */; }; FA0B79481A958E3B000E1D17 /* Vector.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79171A958E3B000E1D17 /* Vector.h */; }; FA0B79491A958E3B000E1D17 /* version.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79181A958E3B000E1D17 /* version.h */; }; - FA0B7A281A958EA3000E1D17 /* Box2D.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B794F1A958EA3000E1D17 /* Box2D.h */; }; - FA0B7A291A958EA3000E1D17 /* b2BroadPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79511A958EA3000E1D17 /* b2BroadPhase.cpp */; }; - FA0B7A2A1A958EA3000E1D17 /* b2BroadPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79511A958EA3000E1D17 /* b2BroadPhase.cpp */; }; - FA0B7A2B1A958EA3000E1D17 /* b2BroadPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79521A958EA3000E1D17 /* b2BroadPhase.h */; }; - FA0B7A2C1A958EA3000E1D17 /* b2CollideCircle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79531A958EA3000E1D17 /* b2CollideCircle.cpp */; }; - FA0B7A2D1A958EA3000E1D17 /* b2CollideCircle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79531A958EA3000E1D17 /* b2CollideCircle.cpp */; }; - FA0B7A2E1A958EA3000E1D17 /* b2CollideEdge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79541A958EA3000E1D17 /* b2CollideEdge.cpp */; }; - FA0B7A2F1A958EA3000E1D17 /* b2CollideEdge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79541A958EA3000E1D17 /* b2CollideEdge.cpp */; }; - FA0B7A301A958EA3000E1D17 /* b2CollidePolygon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79551A958EA3000E1D17 /* b2CollidePolygon.cpp */; }; - FA0B7A311A958EA3000E1D17 /* b2CollidePolygon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79551A958EA3000E1D17 /* b2CollidePolygon.cpp */; }; - FA0B7A321A958EA3000E1D17 /* b2Collision.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79561A958EA3000E1D17 /* b2Collision.cpp */; }; - FA0B7A331A958EA3000E1D17 /* b2Collision.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79561A958EA3000E1D17 /* b2Collision.cpp */; }; - FA0B7A341A958EA3000E1D17 /* b2Collision.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79571A958EA3000E1D17 /* b2Collision.h */; }; - FA0B7A351A958EA3000E1D17 /* b2Distance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79581A958EA3000E1D17 /* b2Distance.cpp */; }; - FA0B7A361A958EA3000E1D17 /* b2Distance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79581A958EA3000E1D17 /* b2Distance.cpp */; }; - FA0B7A371A958EA3000E1D17 /* b2Distance.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79591A958EA3000E1D17 /* b2Distance.h */; }; - FA0B7A381A958EA3000E1D17 /* b2DynamicTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B795A1A958EA3000E1D17 /* b2DynamicTree.cpp */; }; - FA0B7A391A958EA3000E1D17 /* b2DynamicTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B795A1A958EA3000E1D17 /* b2DynamicTree.cpp */; }; - FA0B7A3A1A958EA3000E1D17 /* b2DynamicTree.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B795B1A958EA3000E1D17 /* b2DynamicTree.h */; }; - FA0B7A3B1A958EA3000E1D17 /* b2TimeOfImpact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B795C1A958EA3000E1D17 /* b2TimeOfImpact.cpp */; }; - FA0B7A3C1A958EA3000E1D17 /* b2TimeOfImpact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B795C1A958EA3000E1D17 /* b2TimeOfImpact.cpp */; }; - FA0B7A3D1A958EA3000E1D17 /* b2TimeOfImpact.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B795D1A958EA3000E1D17 /* b2TimeOfImpact.h */; }; - FA0B7A3E1A958EA3000E1D17 /* b2ChainShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B795F1A958EA3000E1D17 /* b2ChainShape.cpp */; }; - FA0B7A3F1A958EA3000E1D17 /* b2ChainShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B795F1A958EA3000E1D17 /* b2ChainShape.cpp */; }; - FA0B7A401A958EA3000E1D17 /* b2ChainShape.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79601A958EA3000E1D17 /* b2ChainShape.h */; }; - FA0B7A411A958EA3000E1D17 /* b2CircleShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79611A958EA3000E1D17 /* b2CircleShape.cpp */; }; - FA0B7A421A958EA3000E1D17 /* b2CircleShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79611A958EA3000E1D17 /* b2CircleShape.cpp */; }; - FA0B7A431A958EA3000E1D17 /* b2CircleShape.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79621A958EA3000E1D17 /* b2CircleShape.h */; }; - FA0B7A441A958EA3000E1D17 /* b2EdgeShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79631A958EA3000E1D17 /* b2EdgeShape.cpp */; }; - FA0B7A451A958EA3000E1D17 /* b2EdgeShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79631A958EA3000E1D17 /* b2EdgeShape.cpp */; }; - FA0B7A461A958EA3000E1D17 /* b2EdgeShape.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79641A958EA3000E1D17 /* b2EdgeShape.h */; }; - FA0B7A471A958EA3000E1D17 /* b2PolygonShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79651A958EA3000E1D17 /* b2PolygonShape.cpp */; }; - FA0B7A481A958EA3000E1D17 /* b2PolygonShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79651A958EA3000E1D17 /* b2PolygonShape.cpp */; }; - FA0B7A491A958EA3000E1D17 /* b2PolygonShape.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79661A958EA3000E1D17 /* b2PolygonShape.h */; }; - FA0B7A4A1A958EA3000E1D17 /* b2Shape.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79671A958EA3000E1D17 /* b2Shape.h */; }; - FA0B7A4B1A958EA3000E1D17 /* b2BlockAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79691A958EA3000E1D17 /* b2BlockAllocator.cpp */; }; - FA0B7A4C1A958EA3000E1D17 /* b2BlockAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79691A958EA3000E1D17 /* b2BlockAllocator.cpp */; }; - FA0B7A4D1A958EA3000E1D17 /* b2BlockAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B796A1A958EA3000E1D17 /* b2BlockAllocator.h */; }; - FA0B7A4E1A958EA3000E1D17 /* b2Draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B796B1A958EA3000E1D17 /* b2Draw.cpp */; }; - FA0B7A4F1A958EA3000E1D17 /* b2Draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B796B1A958EA3000E1D17 /* b2Draw.cpp */; }; - FA0B7A501A958EA3000E1D17 /* b2Draw.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B796C1A958EA3000E1D17 /* b2Draw.h */; }; - FA0B7A511A958EA3000E1D17 /* b2GrowableStack.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B796D1A958EA3000E1D17 /* b2GrowableStack.h */; }; - FA0B7A521A958EA3000E1D17 /* b2Math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B796E1A958EA3000E1D17 /* b2Math.cpp */; }; - FA0B7A531A958EA3000E1D17 /* b2Math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B796E1A958EA3000E1D17 /* b2Math.cpp */; }; - FA0B7A541A958EA3000E1D17 /* b2Math.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B796F1A958EA3000E1D17 /* b2Math.h */; }; - FA0B7A551A958EA3000E1D17 /* b2Settings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79701A958EA3000E1D17 /* b2Settings.cpp */; }; - FA0B7A561A958EA3000E1D17 /* b2Settings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79701A958EA3000E1D17 /* b2Settings.cpp */; }; - FA0B7A571A958EA3000E1D17 /* b2Settings.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79711A958EA3000E1D17 /* b2Settings.h */; }; - FA0B7A581A958EA3000E1D17 /* b2StackAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79721A958EA3000E1D17 /* b2StackAllocator.cpp */; }; - FA0B7A591A958EA3000E1D17 /* b2StackAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79721A958EA3000E1D17 /* b2StackAllocator.cpp */; }; - FA0B7A5A1A958EA3000E1D17 /* b2StackAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79731A958EA3000E1D17 /* b2StackAllocator.h */; }; - FA0B7A5B1A958EA3000E1D17 /* b2Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79741A958EA3000E1D17 /* b2Timer.cpp */; }; - FA0B7A5C1A958EA3000E1D17 /* b2Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79741A958EA3000E1D17 /* b2Timer.cpp */; }; - FA0B7A5D1A958EA3000E1D17 /* b2Timer.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79751A958EA3000E1D17 /* b2Timer.h */; }; - FA0B7A5E1A958EA3000E1D17 /* b2Body.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79771A958EA3000E1D17 /* b2Body.cpp */; }; - FA0B7A5F1A958EA3000E1D17 /* b2Body.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79771A958EA3000E1D17 /* b2Body.cpp */; }; - FA0B7A601A958EA3000E1D17 /* b2Body.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79781A958EA3000E1D17 /* b2Body.h */; }; - FA0B7A611A958EA3000E1D17 /* b2ContactManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79791A958EA3000E1D17 /* b2ContactManager.cpp */; }; - FA0B7A621A958EA3000E1D17 /* b2ContactManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79791A958EA3000E1D17 /* b2ContactManager.cpp */; }; - FA0B7A631A958EA3000E1D17 /* b2ContactManager.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B797A1A958EA3000E1D17 /* b2ContactManager.h */; }; - FA0B7A641A958EA3000E1D17 /* b2Fixture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B797B1A958EA3000E1D17 /* b2Fixture.cpp */; }; - FA0B7A651A958EA3000E1D17 /* b2Fixture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B797B1A958EA3000E1D17 /* b2Fixture.cpp */; }; - FA0B7A661A958EA3000E1D17 /* b2Fixture.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B797C1A958EA3000E1D17 /* b2Fixture.h */; }; - FA0B7A671A958EA3000E1D17 /* b2Island.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B797D1A958EA3000E1D17 /* b2Island.cpp */; }; - FA0B7A681A958EA3000E1D17 /* b2Island.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B797D1A958EA3000E1D17 /* b2Island.cpp */; }; - FA0B7A691A958EA3000E1D17 /* b2Island.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B797E1A958EA3000E1D17 /* b2Island.h */; }; - FA0B7A6A1A958EA3000E1D17 /* b2TimeStep.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B797F1A958EA3000E1D17 /* b2TimeStep.h */; }; - FA0B7A6B1A958EA3000E1D17 /* b2World.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79801A958EA3000E1D17 /* b2World.cpp */; }; - FA0B7A6C1A958EA3000E1D17 /* b2World.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79801A958EA3000E1D17 /* b2World.cpp */; }; - FA0B7A6D1A958EA3000E1D17 /* b2World.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79811A958EA3000E1D17 /* b2World.h */; }; - FA0B7A6E1A958EA3000E1D17 /* b2WorldCallbacks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79821A958EA3000E1D17 /* b2WorldCallbacks.cpp */; }; - FA0B7A6F1A958EA3000E1D17 /* b2WorldCallbacks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79821A958EA3000E1D17 /* b2WorldCallbacks.cpp */; }; - FA0B7A701A958EA3000E1D17 /* b2WorldCallbacks.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79831A958EA3000E1D17 /* b2WorldCallbacks.h */; }; - FA0B7A711A958EA3000E1D17 /* b2ChainAndCircleContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79851A958EA3000E1D17 /* b2ChainAndCircleContact.cpp */; }; - FA0B7A721A958EA3000E1D17 /* b2ChainAndCircleContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79851A958EA3000E1D17 /* b2ChainAndCircleContact.cpp */; }; - FA0B7A731A958EA3000E1D17 /* b2ChainAndCircleContact.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79861A958EA3000E1D17 /* b2ChainAndCircleContact.h */; }; - FA0B7A741A958EA3000E1D17 /* b2ChainAndPolygonContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79871A958EA3000E1D17 /* b2ChainAndPolygonContact.cpp */; }; - FA0B7A751A958EA3000E1D17 /* b2ChainAndPolygonContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79871A958EA3000E1D17 /* b2ChainAndPolygonContact.cpp */; }; - FA0B7A761A958EA3000E1D17 /* b2ChainAndPolygonContact.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79881A958EA3000E1D17 /* b2ChainAndPolygonContact.h */; }; - FA0B7A771A958EA3000E1D17 /* b2CircleContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79891A958EA3000E1D17 /* b2CircleContact.cpp */; }; - FA0B7A781A958EA3000E1D17 /* b2CircleContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79891A958EA3000E1D17 /* b2CircleContact.cpp */; }; - FA0B7A791A958EA3000E1D17 /* b2CircleContact.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B798A1A958EA3000E1D17 /* b2CircleContact.h */; }; - FA0B7A7A1A958EA3000E1D17 /* b2Contact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B798B1A958EA3000E1D17 /* b2Contact.cpp */; }; - FA0B7A7B1A958EA3000E1D17 /* b2Contact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B798B1A958EA3000E1D17 /* b2Contact.cpp */; }; - FA0B7A7C1A958EA3000E1D17 /* b2Contact.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B798C1A958EA3000E1D17 /* b2Contact.h */; }; - FA0B7A7D1A958EA3000E1D17 /* b2ContactSolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B798D1A958EA3000E1D17 /* b2ContactSolver.cpp */; }; - FA0B7A7E1A958EA3000E1D17 /* b2ContactSolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B798D1A958EA3000E1D17 /* b2ContactSolver.cpp */; }; - FA0B7A7F1A958EA3000E1D17 /* b2ContactSolver.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B798E1A958EA3000E1D17 /* b2ContactSolver.h */; }; - FA0B7A801A958EA3000E1D17 /* b2EdgeAndCircleContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B798F1A958EA3000E1D17 /* b2EdgeAndCircleContact.cpp */; }; - FA0B7A811A958EA3000E1D17 /* b2EdgeAndCircleContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B798F1A958EA3000E1D17 /* b2EdgeAndCircleContact.cpp */; }; - FA0B7A821A958EA3000E1D17 /* b2EdgeAndCircleContact.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79901A958EA3000E1D17 /* b2EdgeAndCircleContact.h */; }; - FA0B7A831A958EA3000E1D17 /* b2EdgeAndPolygonContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79911A958EA3000E1D17 /* b2EdgeAndPolygonContact.cpp */; }; - FA0B7A841A958EA3000E1D17 /* b2EdgeAndPolygonContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79911A958EA3000E1D17 /* b2EdgeAndPolygonContact.cpp */; }; - FA0B7A851A958EA3000E1D17 /* b2EdgeAndPolygonContact.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79921A958EA3000E1D17 /* b2EdgeAndPolygonContact.h */; }; - FA0B7A861A958EA3000E1D17 /* b2PolygonAndCircleContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79931A958EA3000E1D17 /* b2PolygonAndCircleContact.cpp */; }; - FA0B7A871A958EA3000E1D17 /* b2PolygonAndCircleContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79931A958EA3000E1D17 /* b2PolygonAndCircleContact.cpp */; }; - FA0B7A881A958EA3000E1D17 /* b2PolygonAndCircleContact.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79941A958EA3000E1D17 /* b2PolygonAndCircleContact.h */; }; - FA0B7A891A958EA3000E1D17 /* b2PolygonContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79951A958EA3000E1D17 /* b2PolygonContact.cpp */; }; - FA0B7A8A1A958EA3000E1D17 /* b2PolygonContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79951A958EA3000E1D17 /* b2PolygonContact.cpp */; }; - FA0B7A8B1A958EA3000E1D17 /* b2PolygonContact.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79961A958EA3000E1D17 /* b2PolygonContact.h */; }; - FA0B7A8C1A958EA3000E1D17 /* b2DistanceJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79981A958EA3000E1D17 /* b2DistanceJoint.cpp */; }; - FA0B7A8D1A958EA3000E1D17 /* b2DistanceJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79981A958EA3000E1D17 /* b2DistanceJoint.cpp */; }; - FA0B7A8E1A958EA3000E1D17 /* b2DistanceJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79991A958EA3000E1D17 /* b2DistanceJoint.h */; }; - FA0B7A8F1A958EA3000E1D17 /* b2FrictionJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B799A1A958EA3000E1D17 /* b2FrictionJoint.cpp */; }; - FA0B7A901A958EA3000E1D17 /* b2FrictionJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B799A1A958EA3000E1D17 /* b2FrictionJoint.cpp */; }; - FA0B7A911A958EA3000E1D17 /* b2FrictionJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B799B1A958EA3000E1D17 /* b2FrictionJoint.h */; }; - FA0B7A921A958EA3000E1D17 /* b2GearJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B799C1A958EA3000E1D17 /* b2GearJoint.cpp */; }; - FA0B7A931A958EA3000E1D17 /* b2GearJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B799C1A958EA3000E1D17 /* b2GearJoint.cpp */; }; - FA0B7A941A958EA3000E1D17 /* b2GearJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B799D1A958EA3000E1D17 /* b2GearJoint.h */; }; - FA0B7A951A958EA3000E1D17 /* b2Joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B799E1A958EA3000E1D17 /* b2Joint.cpp */; }; - FA0B7A961A958EA3000E1D17 /* b2Joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B799E1A958EA3000E1D17 /* b2Joint.cpp */; }; - FA0B7A971A958EA3000E1D17 /* b2Joint.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B799F1A958EA3000E1D17 /* b2Joint.h */; }; - FA0B7A981A958EA3000E1D17 /* b2MotorJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79A01A958EA3000E1D17 /* b2MotorJoint.cpp */; }; - FA0B7A991A958EA3000E1D17 /* b2MotorJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79A01A958EA3000E1D17 /* b2MotorJoint.cpp */; }; - FA0B7A9A1A958EA3000E1D17 /* b2MotorJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79A11A958EA3000E1D17 /* b2MotorJoint.h */; }; - FA0B7A9B1A958EA3000E1D17 /* b2MouseJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79A21A958EA3000E1D17 /* b2MouseJoint.cpp */; }; - FA0B7A9C1A958EA3000E1D17 /* b2MouseJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79A21A958EA3000E1D17 /* b2MouseJoint.cpp */; }; - FA0B7A9D1A958EA3000E1D17 /* b2MouseJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79A31A958EA3000E1D17 /* b2MouseJoint.h */; }; - FA0B7A9E1A958EA3000E1D17 /* b2PrismaticJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79A41A958EA3000E1D17 /* b2PrismaticJoint.cpp */; }; - FA0B7A9F1A958EA3000E1D17 /* b2PrismaticJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79A41A958EA3000E1D17 /* b2PrismaticJoint.cpp */; }; - FA0B7AA01A958EA3000E1D17 /* b2PrismaticJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79A51A958EA3000E1D17 /* b2PrismaticJoint.h */; }; - FA0B7AA11A958EA3000E1D17 /* b2PulleyJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79A61A958EA3000E1D17 /* b2PulleyJoint.cpp */; }; - FA0B7AA21A958EA3000E1D17 /* b2PulleyJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79A61A958EA3000E1D17 /* b2PulleyJoint.cpp */; }; - FA0B7AA31A958EA3000E1D17 /* b2PulleyJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79A71A958EA3000E1D17 /* b2PulleyJoint.h */; }; - FA0B7AA41A958EA3000E1D17 /* b2RevoluteJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79A81A958EA3000E1D17 /* b2RevoluteJoint.cpp */; }; - FA0B7AA51A958EA3000E1D17 /* b2RevoluteJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79A81A958EA3000E1D17 /* b2RevoluteJoint.cpp */; }; - FA0B7AA61A958EA3000E1D17 /* b2RevoluteJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79A91A958EA3000E1D17 /* b2RevoluteJoint.h */; }; - FA0B7AA71A958EA3000E1D17 /* b2RopeJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79AA1A958EA3000E1D17 /* b2RopeJoint.cpp */; }; - FA0B7AA81A958EA3000E1D17 /* b2RopeJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79AA1A958EA3000E1D17 /* b2RopeJoint.cpp */; }; - FA0B7AA91A958EA3000E1D17 /* b2RopeJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79AB1A958EA3000E1D17 /* b2RopeJoint.h */; }; - FA0B7AAA1A958EA3000E1D17 /* b2WeldJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79AC1A958EA3000E1D17 /* b2WeldJoint.cpp */; }; - FA0B7AAB1A958EA3000E1D17 /* b2WeldJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79AC1A958EA3000E1D17 /* b2WeldJoint.cpp */; }; - FA0B7AAC1A958EA3000E1D17 /* b2WeldJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79AD1A958EA3000E1D17 /* b2WeldJoint.h */; }; - FA0B7AAD1A958EA3000E1D17 /* b2WheelJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79AE1A958EA3000E1D17 /* b2WheelJoint.cpp */; }; - FA0B7AAE1A958EA3000E1D17 /* b2WheelJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79AE1A958EA3000E1D17 /* b2WheelJoint.cpp */; }; - FA0B7AAF1A958EA3000E1D17 /* b2WheelJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79AF1A958EA3000E1D17 /* b2WheelJoint.h */; }; - FA0B7AB11A958EA3000E1D17 /* b2Rope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79B21A958EA3000E1D17 /* b2Rope.cpp */; }; - FA0B7AB21A958EA3000E1D17 /* b2Rope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79B21A958EA3000E1D17 /* b2Rope.cpp */; }; - FA0B7AB31A958EA3000E1D17 /* b2Rope.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79B31A958EA3000E1D17 /* b2Rope.h */; }; FA0B7AB41A958EA3000E1D17 /* ddsinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79B51A958EA3000E1D17 /* ddsinfo.h */; }; FA0B7AB51A958EA3000E1D17 /* ddsparse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79B61A958EA3000E1D17 /* ddsparse.cpp */; }; FA0B7AB61A958EA3000E1D17 /* ddsparse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79B61A958EA3000E1D17 /* ddsparse.cpp */; }; @@ -968,6 +829,149 @@ FAB2D5AA1AABDD8A008224A4 /* TrueTypeRasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB2D5A81AABDD8A008224A4 /* TrueTypeRasterizer.cpp */; }; FAB2D5AB1AABDD8A008224A4 /* TrueTypeRasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB2D5A81AABDD8A008224A4 /* TrueTypeRasterizer.cpp */; }; FAB2D5AC1AABDD8A008224A4 /* TrueTypeRasterizer.h in Headers */ = {isa = PBXBuildFile; fileRef = FAB2D5A91AABDD8A008224A4 /* TrueTypeRasterizer.h */; }; + FABDA9762552448200B5C523 /* b2_joint.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9112552448200B5C523 /* b2_joint.h */; }; + FABDA9772552448200B5C523 /* b2_shape.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9122552448200B5C523 /* b2_shape.h */; }; + FABDA9782552448200B5C523 /* b2_block_allocator.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9132552448200B5C523 /* b2_block_allocator.h */; }; + FABDA9792552448200B5C523 /* b2_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9152552448200B5C523 /* b2_joint.cpp */; }; + FABDA97A2552448200B5C523 /* b2_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9152552448200B5C523 /* b2_joint.cpp */; }; + FABDA97B2552448200B5C523 /* b2_chain_polygon_contact.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9162552448200B5C523 /* b2_chain_polygon_contact.h */; }; + FABDA97C2552448200B5C523 /* b2_chain_circle_contact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9172552448200B5C523 /* b2_chain_circle_contact.cpp */; }; + FABDA97D2552448200B5C523 /* b2_chain_circle_contact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9172552448200B5C523 /* b2_chain_circle_contact.cpp */; }; + FABDA97E2552448200B5C523 /* b2_chain_circle_contact.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9182552448200B5C523 /* b2_chain_circle_contact.h */; }; + FABDA97F2552448200B5C523 /* b2_polygon_circle_contact.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9192552448200B5C523 /* b2_polygon_circle_contact.h */; }; + FABDA9802552448200B5C523 /* b2_circle_contact.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA91A2552448200B5C523 /* b2_circle_contact.h */; }; + FABDA9812552448200B5C523 /* b2_weld_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA91B2552448200B5C523 /* b2_weld_joint.cpp */; }; + FABDA9822552448200B5C523 /* b2_weld_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA91B2552448200B5C523 /* b2_weld_joint.cpp */; }; + FABDA9832552448200B5C523 /* b2_chain_polygon_contact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA91C2552448200B5C523 /* b2_chain_polygon_contact.cpp */; }; + FABDA9842552448200B5C523 /* b2_chain_polygon_contact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA91C2552448200B5C523 /* b2_chain_polygon_contact.cpp */; }; + FABDA9852552448200B5C523 /* b2_edge_circle_contact.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA91D2552448200B5C523 /* b2_edge_circle_contact.h */; }; + FABDA9862552448200B5C523 /* b2_body.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA91E2552448200B5C523 /* b2_body.cpp */; }; + FABDA9872552448200B5C523 /* b2_body.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA91E2552448200B5C523 /* b2_body.cpp */; }; + FABDA9882552448300B5C523 /* b2_contact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA91F2552448200B5C523 /* b2_contact.cpp */; }; + FABDA9892552448300B5C523 /* b2_contact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA91F2552448200B5C523 /* b2_contact.cpp */; }; + FABDA98A2552448300B5C523 /* b2_revolute_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9202552448200B5C523 /* b2_revolute_joint.cpp */; }; + FABDA98B2552448300B5C523 /* b2_revolute_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9202552448200B5C523 /* b2_revolute_joint.cpp */; }; + FABDA98C2552448300B5C523 /* b2_contact_solver.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9212552448200B5C523 /* b2_contact_solver.h */; }; + FABDA98D2552448300B5C523 /* b2_contact_solver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9222552448200B5C523 /* b2_contact_solver.cpp */; }; + FABDA98E2552448300B5C523 /* b2_contact_solver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9222552448200B5C523 /* b2_contact_solver.cpp */; }; + FABDA98F2552448300B5C523 /* b2_world_callbacks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9232552448200B5C523 /* b2_world_callbacks.cpp */; }; + FABDA9902552448300B5C523 /* b2_world_callbacks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9232552448200B5C523 /* b2_world_callbacks.cpp */; }; + FABDA9912552448300B5C523 /* b2_pulley_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9242552448200B5C523 /* b2_pulley_joint.cpp */; }; + FABDA9922552448300B5C523 /* b2_pulley_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9242552448200B5C523 /* b2_pulley_joint.cpp */; }; + FABDA9932552448300B5C523 /* b2_polygon_circle_contact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9252552448200B5C523 /* b2_polygon_circle_contact.cpp */; }; + FABDA9942552448300B5C523 /* b2_polygon_circle_contact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9252552448200B5C523 /* b2_polygon_circle_contact.cpp */; }; + FABDA9952552448300B5C523 /* b2_edge_polygon_contact.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9262552448200B5C523 /* b2_edge_polygon_contact.h */; }; + FABDA9962552448300B5C523 /* b2_distance_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9272552448200B5C523 /* b2_distance_joint.cpp */; }; + FABDA9972552448300B5C523 /* b2_distance_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9272552448200B5C523 /* b2_distance_joint.cpp */; }; + FABDA9982552448300B5C523 /* b2_contact_manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9282552448200B5C523 /* b2_contact_manager.cpp */; }; + FABDA9992552448300B5C523 /* b2_contact_manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9282552448200B5C523 /* b2_contact_manager.cpp */; }; + FABDA99A2552448300B5C523 /* b2_polygon_contact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9292552448200B5C523 /* b2_polygon_contact.cpp */; }; + FABDA99B2552448300B5C523 /* b2_polygon_contact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9292552448200B5C523 /* b2_polygon_contact.cpp */; }; + FABDA99C2552448300B5C523 /* b2_edge_polygon_contact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA92A2552448200B5C523 /* b2_edge_polygon_contact.cpp */; }; + FABDA99D2552448300B5C523 /* b2_edge_polygon_contact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA92A2552448200B5C523 /* b2_edge_polygon_contact.cpp */; }; + FABDA99E2552448300B5C523 /* b2_edge_circle_contact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA92B2552448200B5C523 /* b2_edge_circle_contact.cpp */; }; + FABDA99F2552448300B5C523 /* b2_edge_circle_contact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA92B2552448200B5C523 /* b2_edge_circle_contact.cpp */; }; + FABDA9A02552448300B5C523 /* b2_gear_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA92C2552448200B5C523 /* b2_gear_joint.cpp */; }; + FABDA9A12552448300B5C523 /* b2_gear_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA92C2552448200B5C523 /* b2_gear_joint.cpp */; }; + FABDA9A22552448300B5C523 /* b2_friction_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA92D2552448200B5C523 /* b2_friction_joint.cpp */; }; + FABDA9A32552448300B5C523 /* b2_friction_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA92D2552448200B5C523 /* b2_friction_joint.cpp */; }; + FABDA9A42552448300B5C523 /* b2_wheel_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA92E2552448200B5C523 /* b2_wheel_joint.cpp */; }; + FABDA9A52552448300B5C523 /* b2_wheel_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA92E2552448200B5C523 /* b2_wheel_joint.cpp */; }; + FABDA9A62552448300B5C523 /* b2_polygon_contact.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA92F2552448200B5C523 /* b2_polygon_contact.h */; }; + FABDA9A72552448300B5C523 /* b2_motor_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9302552448200B5C523 /* b2_motor_joint.cpp */; }; + FABDA9A82552448300B5C523 /* b2_motor_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9302552448200B5C523 /* b2_motor_joint.cpp */; }; + FABDA9A92552448300B5C523 /* b2_rope_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9312552448200B5C523 /* b2_rope_joint.cpp */; }; + FABDA9AA2552448300B5C523 /* b2_rope_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9312552448200B5C523 /* b2_rope_joint.cpp */; }; + FABDA9AB2552448300B5C523 /* b2_world.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9322552448200B5C523 /* b2_world.cpp */; }; + FABDA9AC2552448300B5C523 /* b2_world.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9322552448200B5C523 /* b2_world.cpp */; }; + FABDA9AD2552448300B5C523 /* b2_island.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9332552448200B5C523 /* b2_island.cpp */; }; + FABDA9AE2552448300B5C523 /* b2_island.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9332552448200B5C523 /* b2_island.cpp */; }; + FABDA9AF2552448300B5C523 /* b2_mouse_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9342552448200B5C523 /* b2_mouse_joint.cpp */; }; + FABDA9B02552448300B5C523 /* b2_mouse_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9342552448200B5C523 /* b2_mouse_joint.cpp */; }; + FABDA9B12552448300B5C523 /* b2_circle_contact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9352552448200B5C523 /* b2_circle_contact.cpp */; }; + FABDA9B22552448300B5C523 /* b2_circle_contact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9352552448200B5C523 /* b2_circle_contact.cpp */; }; + FABDA9B32552448300B5C523 /* b2_prismatic_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9362552448200B5C523 /* b2_prismatic_joint.cpp */; }; + FABDA9B42552448300B5C523 /* b2_prismatic_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9362552448200B5C523 /* b2_prismatic_joint.cpp */; }; + FABDA9B52552448300B5C523 /* b2_fixture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9372552448200B5C523 /* b2_fixture.cpp */; }; + FABDA9B62552448300B5C523 /* b2_fixture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9372552448200B5C523 /* b2_fixture.cpp */; }; + FABDA9B72552448300B5C523 /* b2_island.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9382552448200B5C523 /* b2_island.h */; }; + FABDA9B82552448300B5C523 /* b2_motor_joint.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9392552448200B5C523 /* b2_motor_joint.h */; }; + FABDA9B92552448300B5C523 /* b2_common.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA93A2552448200B5C523 /* b2_common.h */; }; + FABDA9BA2552448300B5C523 /* b2_weld_joint.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA93B2552448200B5C523 /* b2_weld_joint.h */; }; + FABDA9BB2552448300B5C523 /* b2_dynamic_tree.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA93C2552448200B5C523 /* b2_dynamic_tree.h */; }; + FABDA9BC2552448300B5C523 /* b2_fixture.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA93D2552448200B5C523 /* b2_fixture.h */; }; + FABDA9BD2552448300B5C523 /* b2_stack_allocator.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA93E2552448200B5C523 /* b2_stack_allocator.h */; }; + FABDA9BE2552448300B5C523 /* Box2D.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA93F2552448200B5C523 /* Box2D.h */; }; + FABDA9BF2552448300B5C523 /* b2_types.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9402552448200B5C523 /* b2_types.h */; }; + FABDA9C02552448300B5C523 /* b2_broad_phase.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9412552448200B5C523 /* b2_broad_phase.h */; }; + FABDA9C12552448300B5C523 /* b2_rope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9432552448200B5C523 /* b2_rope.cpp */; }; + FABDA9C22552448300B5C523 /* b2_rope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9432552448200B5C523 /* b2_rope.cpp */; }; + FABDA9C32552448300B5C523 /* b2_settings.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9442552448200B5C523 /* b2_settings.h */; }; + FABDA9C42552448300B5C523 /* b2_revolute_joint.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9452552448200B5C523 /* b2_revolute_joint.h */; }; + FABDA9C52552448300B5C523 /* README.MODIFIED in Resources */ = {isa = PBXBuildFile; fileRef = FABDA9462552448200B5C523 /* README.MODIFIED */; }; + FABDA9C62552448300B5C523 /* b2_rope.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9472552448200B5C523 /* b2_rope.h */; }; + FABDA9C72552448300B5C523 /* b2_distance_joint.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9482552448200B5C523 /* b2_distance_joint.h */; }; + FABDA9C82552448300B5C523 /* b2_body.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9492552448200B5C523 /* b2_body.h */; }; + FABDA9C92552448300B5C523 /* b2_distance.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA94A2552448200B5C523 /* b2_distance.h */; }; + FABDA9CA2552448300B5C523 /* b2_time_step.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA94B2552448200B5C523 /* b2_time_step.h */; }; + FABDA9CB2552448300B5C523 /* b2_pulley_joint.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA94C2552448200B5C523 /* b2_pulley_joint.h */; }; + FABDA9CC2552448300B5C523 /* b2_circle_shape.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA94D2552448200B5C523 /* b2_circle_shape.h */; }; + FABDA9CD2552448300B5C523 /* b2_math.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA94E2552448200B5C523 /* b2_math.h */; }; + FABDA9CE2552448300B5C523 /* b2_time_of_impact.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA94F2552448200B5C523 /* b2_time_of_impact.h */; }; + FABDA9CF2552448300B5C523 /* b2_mouse_joint.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9502552448200B5C523 /* b2_mouse_joint.h */; }; + FABDA9D02552448300B5C523 /* b2_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9522552448200B5C523 /* b2_draw.cpp */; }; + FABDA9D12552448300B5C523 /* b2_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9522552448200B5C523 /* b2_draw.cpp */; }; + FABDA9D22552448300B5C523 /* b2_timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9532552448200B5C523 /* b2_timer.cpp */; }; + FABDA9D32552448300B5C523 /* b2_timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9532552448200B5C523 /* b2_timer.cpp */; }; + FABDA9D42552448300B5C523 /* b2_block_allocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9542552448200B5C523 /* b2_block_allocator.cpp */; }; + FABDA9D52552448300B5C523 /* b2_block_allocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9542552448200B5C523 /* b2_block_allocator.cpp */; }; + FABDA9D62552448300B5C523 /* b2_stack_allocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9552552448200B5C523 /* b2_stack_allocator.cpp */; }; + FABDA9D72552448300B5C523 /* b2_stack_allocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9552552448200B5C523 /* b2_stack_allocator.cpp */; }; + FABDA9D82552448300B5C523 /* b2_settings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9562552448200B5C523 /* b2_settings.cpp */; }; + FABDA9D92552448300B5C523 /* b2_settings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9562552448200B5C523 /* b2_settings.cpp */; }; + FABDA9DA2552448300B5C523 /* b2_math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9572552448200B5C523 /* b2_math.cpp */; }; + FABDA9DB2552448300B5C523 /* b2_math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9572552448200B5C523 /* b2_math.cpp */; }; + FABDA9DC2552448300B5C523 /* b2_friction_joint.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9582552448200B5C523 /* b2_friction_joint.h */; }; + FABDA9DD2552448300B5C523 /* b2_contact.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9592552448200B5C523 /* b2_contact.h */; }; + FABDA9DE2552448300B5C523 /* b2_prismatic_joint.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA95A2552448200B5C523 /* b2_prismatic_joint.h */; }; + FABDA9DF2552448300B5C523 /* b2_world.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA95B2552448200B5C523 /* b2_world.h */; }; + FABDA9E02552448300B5C523 /* b2_polygon_shape.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA95C2552448200B5C523 /* b2_polygon_shape.h */; }; + FABDA9E12552448300B5C523 /* b2_wheel_joint.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA95D2552448200B5C523 /* b2_wheel_joint.h */; }; + FABDA9E22552448300B5C523 /* b2_growable_stack.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA95E2552448200B5C523 /* b2_growable_stack.h */; }; + FABDA9E32552448300B5C523 /* b2_draw.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA95F2552448200B5C523 /* b2_draw.h */; }; + FABDA9E42552448300B5C523 /* b2_collision.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9602552448200B5C523 /* b2_collision.h */; }; + FABDA9E52552448300B5C523 /* b2_rope_joint.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9612552448200B5C523 /* b2_rope_joint.h */; }; + FABDA9E62552448300B5C523 /* b2_api.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9622552448200B5C523 /* b2_api.h */; }; + FABDA9E72552448300B5C523 /* b2_chain_shape.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9632552448200B5C523 /* b2_chain_shape.h */; }; + FABDA9E82552448300B5C523 /* b2_gear_joint.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9642552448200B5C523 /* b2_gear_joint.h */; }; + FABDA9E92552448300B5C523 /* b2_timer.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9652552448200B5C523 /* b2_timer.h */; }; + FABDA9EA2552448300B5C523 /* b2_world_callbacks.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9662552448200B5C523 /* b2_world_callbacks.h */; }; + FABDA9EB2552448300B5C523 /* b2_collide_circle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9682552448200B5C523 /* b2_collide_circle.cpp */; }; + FABDA9EC2552448300B5C523 /* b2_collide_circle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9682552448200B5C523 /* b2_collide_circle.cpp */; }; + FABDA9ED2552448300B5C523 /* b2_circle_shape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9692552448200B5C523 /* b2_circle_shape.cpp */; }; + FABDA9EE2552448300B5C523 /* b2_circle_shape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9692552448200B5C523 /* b2_circle_shape.cpp */; }; + FABDA9EF2552448300B5C523 /* b2_collision.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA96A2552448200B5C523 /* b2_collision.cpp */; }; + FABDA9F02552448300B5C523 /* b2_collision.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA96A2552448200B5C523 /* b2_collision.cpp */; }; + FABDA9F12552448300B5C523 /* b2_collide_edge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA96B2552448200B5C523 /* b2_collide_edge.cpp */; }; + FABDA9F22552448300B5C523 /* b2_collide_edge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA96B2552448200B5C523 /* b2_collide_edge.cpp */; }; + FABDA9F32552448300B5C523 /* b2_chain_shape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA96C2552448200B5C523 /* b2_chain_shape.cpp */; }; + FABDA9F42552448300B5C523 /* b2_chain_shape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA96C2552448200B5C523 /* b2_chain_shape.cpp */; }; + FABDA9F52552448300B5C523 /* b2_broad_phase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA96D2552448200B5C523 /* b2_broad_phase.cpp */; }; + FABDA9F62552448300B5C523 /* b2_broad_phase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA96D2552448200B5C523 /* b2_broad_phase.cpp */; }; + FABDA9F72552448300B5C523 /* b2_dynamic_tree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA96E2552448200B5C523 /* b2_dynamic_tree.cpp */; }; + FABDA9F82552448300B5C523 /* b2_dynamic_tree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA96E2552448200B5C523 /* b2_dynamic_tree.cpp */; }; + FABDA9F92552448300B5C523 /* b2_polygon_shape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA96F2552448200B5C523 /* b2_polygon_shape.cpp */; }; + FABDA9FA2552448300B5C523 /* b2_polygon_shape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA96F2552448200B5C523 /* b2_polygon_shape.cpp */; }; + FABDA9FB2552448300B5C523 /* b2_collide_polygon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9702552448200B5C523 /* b2_collide_polygon.cpp */; }; + FABDA9FC2552448300B5C523 /* b2_collide_polygon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9702552448200B5C523 /* b2_collide_polygon.cpp */; }; + FABDA9FD2552448300B5C523 /* b2_edge_shape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9712552448200B5C523 /* b2_edge_shape.cpp */; }; + FABDA9FE2552448300B5C523 /* b2_edge_shape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9712552448200B5C523 /* b2_edge_shape.cpp */; }; + FABDA9FF2552448300B5C523 /* b2_time_of_impact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9722552448200B5C523 /* b2_time_of_impact.cpp */; }; + FABDAA002552448300B5C523 /* b2_time_of_impact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9722552448200B5C523 /* b2_time_of_impact.cpp */; }; + FABDAA012552448300B5C523 /* b2_distance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9732552448200B5C523 /* b2_distance.cpp */; }; + FABDAA022552448300B5C523 /* b2_distance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9732552448200B5C523 /* b2_distance.cpp */; }; + FABDAA032552448300B5C523 /* b2_contact_manager.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9742552448200B5C523 /* b2_contact_manager.h */; }; + FABDAA042552448300B5C523 /* b2_edge_shape.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9752552448200B5C523 /* b2_edge_shape.h */; }; FAC271E523B5B5B400C200D3 /* renderstate.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC271E323B5B5B400C200D3 /* renderstate.h */; }; FAC271E623B5B5B400C200D3 /* renderstate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC271E423B5B5B400C200D3 /* renderstate.cpp */; }; FAC271E723B5B5B400C200D3 /* renderstate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC271E423B5B5B400C200D3 /* renderstate.cpp */; }; @@ -1335,99 +1339,6 @@ FA0B79161A958E3B000E1D17 /* Vector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Vector.cpp; sourceTree = ""; }; FA0B79171A958E3B000E1D17 /* Vector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Vector.h; sourceTree = ""; }; FA0B79181A958E3B000E1D17 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = ""; }; - FA0B794F1A958EA3000E1D17 /* Box2D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Box2D.h; sourceTree = ""; }; - FA0B79511A958EA3000E1D17 /* b2BroadPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2BroadPhase.cpp; sourceTree = ""; }; - FA0B79521A958EA3000E1D17 /* b2BroadPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2BroadPhase.h; sourceTree = ""; }; - FA0B79531A958EA3000E1D17 /* b2CollideCircle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2CollideCircle.cpp; sourceTree = ""; }; - FA0B79541A958EA3000E1D17 /* b2CollideEdge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2CollideEdge.cpp; sourceTree = ""; }; - FA0B79551A958EA3000E1D17 /* b2CollidePolygon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2CollidePolygon.cpp; sourceTree = ""; }; - FA0B79561A958EA3000E1D17 /* b2Collision.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Collision.cpp; sourceTree = ""; }; - FA0B79571A958EA3000E1D17 /* b2Collision.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Collision.h; sourceTree = ""; }; - FA0B79581A958EA3000E1D17 /* b2Distance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Distance.cpp; sourceTree = ""; }; - FA0B79591A958EA3000E1D17 /* b2Distance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Distance.h; sourceTree = ""; }; - FA0B795A1A958EA3000E1D17 /* b2DynamicTree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2DynamicTree.cpp; sourceTree = ""; }; - FA0B795B1A958EA3000E1D17 /* b2DynamicTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2DynamicTree.h; sourceTree = ""; }; - FA0B795C1A958EA3000E1D17 /* b2TimeOfImpact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2TimeOfImpact.cpp; sourceTree = ""; }; - FA0B795D1A958EA3000E1D17 /* b2TimeOfImpact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2TimeOfImpact.h; sourceTree = ""; }; - FA0B795F1A958EA3000E1D17 /* b2ChainShape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2ChainShape.cpp; sourceTree = ""; }; - FA0B79601A958EA3000E1D17 /* b2ChainShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2ChainShape.h; sourceTree = ""; }; - FA0B79611A958EA3000E1D17 /* b2CircleShape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2CircleShape.cpp; sourceTree = ""; }; - FA0B79621A958EA3000E1D17 /* b2CircleShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2CircleShape.h; sourceTree = ""; }; - FA0B79631A958EA3000E1D17 /* b2EdgeShape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2EdgeShape.cpp; sourceTree = ""; }; - FA0B79641A958EA3000E1D17 /* b2EdgeShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2EdgeShape.h; sourceTree = ""; }; - FA0B79651A958EA3000E1D17 /* b2PolygonShape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PolygonShape.cpp; sourceTree = ""; }; - FA0B79661A958EA3000E1D17 /* b2PolygonShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PolygonShape.h; sourceTree = ""; }; - FA0B79671A958EA3000E1D17 /* b2Shape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Shape.h; sourceTree = ""; }; - FA0B79691A958EA3000E1D17 /* b2BlockAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2BlockAllocator.cpp; sourceTree = ""; }; - FA0B796A1A958EA3000E1D17 /* b2BlockAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2BlockAllocator.h; sourceTree = ""; }; - FA0B796B1A958EA3000E1D17 /* b2Draw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Draw.cpp; sourceTree = ""; }; - FA0B796C1A958EA3000E1D17 /* b2Draw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Draw.h; sourceTree = ""; }; - FA0B796D1A958EA3000E1D17 /* b2GrowableStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2GrowableStack.h; sourceTree = ""; }; - FA0B796E1A958EA3000E1D17 /* b2Math.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Math.cpp; sourceTree = ""; }; - FA0B796F1A958EA3000E1D17 /* b2Math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Math.h; sourceTree = ""; }; - FA0B79701A958EA3000E1D17 /* b2Settings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Settings.cpp; sourceTree = ""; }; - FA0B79711A958EA3000E1D17 /* b2Settings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Settings.h; sourceTree = ""; }; - FA0B79721A958EA3000E1D17 /* b2StackAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2StackAllocator.cpp; sourceTree = ""; }; - FA0B79731A958EA3000E1D17 /* b2StackAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2StackAllocator.h; sourceTree = ""; }; - FA0B79741A958EA3000E1D17 /* b2Timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Timer.cpp; sourceTree = ""; }; - FA0B79751A958EA3000E1D17 /* b2Timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Timer.h; sourceTree = ""; }; - FA0B79771A958EA3000E1D17 /* b2Body.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Body.cpp; sourceTree = ""; }; - FA0B79781A958EA3000E1D17 /* b2Body.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Body.h; sourceTree = ""; }; - FA0B79791A958EA3000E1D17 /* b2ContactManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2ContactManager.cpp; sourceTree = ""; }; - FA0B797A1A958EA3000E1D17 /* b2ContactManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2ContactManager.h; sourceTree = ""; }; - FA0B797B1A958EA3000E1D17 /* b2Fixture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Fixture.cpp; sourceTree = ""; }; - FA0B797C1A958EA3000E1D17 /* b2Fixture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Fixture.h; sourceTree = ""; }; - FA0B797D1A958EA3000E1D17 /* b2Island.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Island.cpp; sourceTree = ""; }; - FA0B797E1A958EA3000E1D17 /* b2Island.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Island.h; sourceTree = ""; }; - FA0B797F1A958EA3000E1D17 /* b2TimeStep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2TimeStep.h; sourceTree = ""; }; - FA0B79801A958EA3000E1D17 /* b2World.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2World.cpp; sourceTree = ""; }; - FA0B79811A958EA3000E1D17 /* b2World.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2World.h; sourceTree = ""; }; - FA0B79821A958EA3000E1D17 /* b2WorldCallbacks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2WorldCallbacks.cpp; sourceTree = ""; }; - FA0B79831A958EA3000E1D17 /* b2WorldCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2WorldCallbacks.h; sourceTree = ""; }; - FA0B79851A958EA3000E1D17 /* b2ChainAndCircleContact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2ChainAndCircleContact.cpp; sourceTree = ""; }; - FA0B79861A958EA3000E1D17 /* b2ChainAndCircleContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2ChainAndCircleContact.h; sourceTree = ""; }; - FA0B79871A958EA3000E1D17 /* b2ChainAndPolygonContact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2ChainAndPolygonContact.cpp; sourceTree = ""; }; - FA0B79881A958EA3000E1D17 /* b2ChainAndPolygonContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2ChainAndPolygonContact.h; sourceTree = ""; }; - FA0B79891A958EA3000E1D17 /* b2CircleContact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2CircleContact.cpp; sourceTree = ""; }; - FA0B798A1A958EA3000E1D17 /* b2CircleContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2CircleContact.h; sourceTree = ""; }; - FA0B798B1A958EA3000E1D17 /* b2Contact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Contact.cpp; sourceTree = ""; }; - FA0B798C1A958EA3000E1D17 /* b2Contact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Contact.h; sourceTree = ""; }; - FA0B798D1A958EA3000E1D17 /* b2ContactSolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2ContactSolver.cpp; sourceTree = ""; }; - FA0B798E1A958EA3000E1D17 /* b2ContactSolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2ContactSolver.h; sourceTree = ""; }; - FA0B798F1A958EA3000E1D17 /* b2EdgeAndCircleContact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2EdgeAndCircleContact.cpp; sourceTree = ""; }; - FA0B79901A958EA3000E1D17 /* b2EdgeAndCircleContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2EdgeAndCircleContact.h; sourceTree = ""; }; - FA0B79911A958EA3000E1D17 /* b2EdgeAndPolygonContact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2EdgeAndPolygonContact.cpp; sourceTree = ""; }; - FA0B79921A958EA3000E1D17 /* b2EdgeAndPolygonContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2EdgeAndPolygonContact.h; sourceTree = ""; }; - FA0B79931A958EA3000E1D17 /* b2PolygonAndCircleContact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PolygonAndCircleContact.cpp; sourceTree = ""; }; - FA0B79941A958EA3000E1D17 /* b2PolygonAndCircleContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PolygonAndCircleContact.h; sourceTree = ""; }; - FA0B79951A958EA3000E1D17 /* b2PolygonContact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PolygonContact.cpp; sourceTree = ""; }; - FA0B79961A958EA3000E1D17 /* b2PolygonContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PolygonContact.h; sourceTree = ""; }; - FA0B79981A958EA3000E1D17 /* b2DistanceJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2DistanceJoint.cpp; sourceTree = ""; }; - FA0B79991A958EA3000E1D17 /* b2DistanceJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2DistanceJoint.h; sourceTree = ""; }; - FA0B799A1A958EA3000E1D17 /* b2FrictionJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2FrictionJoint.cpp; sourceTree = ""; }; - FA0B799B1A958EA3000E1D17 /* b2FrictionJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2FrictionJoint.h; sourceTree = ""; }; - FA0B799C1A958EA3000E1D17 /* b2GearJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2GearJoint.cpp; sourceTree = ""; }; - FA0B799D1A958EA3000E1D17 /* b2GearJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2GearJoint.h; sourceTree = ""; }; - FA0B799E1A958EA3000E1D17 /* b2Joint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Joint.cpp; sourceTree = ""; }; - FA0B799F1A958EA3000E1D17 /* b2Joint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Joint.h; sourceTree = ""; }; - FA0B79A01A958EA3000E1D17 /* b2MotorJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2MotorJoint.cpp; sourceTree = ""; }; - FA0B79A11A958EA3000E1D17 /* b2MotorJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2MotorJoint.h; sourceTree = ""; }; - FA0B79A21A958EA3000E1D17 /* b2MouseJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2MouseJoint.cpp; sourceTree = ""; }; - FA0B79A31A958EA3000E1D17 /* b2MouseJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2MouseJoint.h; sourceTree = ""; }; - FA0B79A41A958EA3000E1D17 /* b2PrismaticJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PrismaticJoint.cpp; sourceTree = ""; }; - FA0B79A51A958EA3000E1D17 /* b2PrismaticJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PrismaticJoint.h; sourceTree = ""; }; - FA0B79A61A958EA3000E1D17 /* b2PulleyJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PulleyJoint.cpp; sourceTree = ""; }; - FA0B79A71A958EA3000E1D17 /* b2PulleyJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PulleyJoint.h; sourceTree = ""; }; - FA0B79A81A958EA3000E1D17 /* b2RevoluteJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2RevoluteJoint.cpp; sourceTree = ""; }; - FA0B79A91A958EA3000E1D17 /* b2RevoluteJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2RevoluteJoint.h; sourceTree = ""; }; - FA0B79AA1A958EA3000E1D17 /* b2RopeJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2RopeJoint.cpp; sourceTree = ""; }; - FA0B79AB1A958EA3000E1D17 /* b2RopeJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2RopeJoint.h; sourceTree = ""; }; - FA0B79AC1A958EA3000E1D17 /* b2WeldJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2WeldJoint.cpp; sourceTree = ""; }; - FA0B79AD1A958EA3000E1D17 /* b2WeldJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2WeldJoint.h; sourceTree = ""; }; - FA0B79AE1A958EA3000E1D17 /* b2WheelJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2WheelJoint.cpp; sourceTree = ""; }; - FA0B79AF1A958EA3000E1D17 /* b2WheelJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2WheelJoint.h; sourceTree = ""; }; - FA0B79B21A958EA3000E1D17 /* b2Rope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Rope.cpp; sourceTree = ""; }; - FA0B79B31A958EA3000E1D17 /* b2Rope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Rope.h; sourceTree = ""; }; FA0B79B51A958EA3000E1D17 /* ddsinfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ddsinfo.h; sourceTree = ""; }; FA0B79B61A958EA3000E1D17 /* ddsparse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ddsparse.cpp; sourceTree = ""; }; FA0B79B71A958EA3000E1D17 /* ddsparse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ddsparse.h; sourceTree = ""; }; @@ -1920,6 +1831,103 @@ FAB17BF41ABFC4B100F9BA27 /* lz4hc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lz4hc.h; sourceTree = ""; }; FAB2D5A81AABDD8A008224A4 /* TrueTypeRasterizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TrueTypeRasterizer.cpp; sourceTree = ""; }; FAB2D5A91AABDD8A008224A4 /* TrueTypeRasterizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrueTypeRasterizer.h; sourceTree = ""; }; + FABDA9112552448200B5C523 /* b2_joint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_joint.h; sourceTree = ""; }; + FABDA9122552448200B5C523 /* b2_shape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_shape.h; sourceTree = ""; }; + FABDA9132552448200B5C523 /* b2_block_allocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_block_allocator.h; sourceTree = ""; }; + FABDA9152552448200B5C523 /* b2_joint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_joint.cpp; sourceTree = ""; }; + FABDA9162552448200B5C523 /* b2_chain_polygon_contact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_chain_polygon_contact.h; sourceTree = ""; }; + FABDA9172552448200B5C523 /* b2_chain_circle_contact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_chain_circle_contact.cpp; sourceTree = ""; }; + FABDA9182552448200B5C523 /* b2_chain_circle_contact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_chain_circle_contact.h; sourceTree = ""; }; + FABDA9192552448200B5C523 /* b2_polygon_circle_contact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_polygon_circle_contact.h; sourceTree = ""; }; + FABDA91A2552448200B5C523 /* b2_circle_contact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_circle_contact.h; sourceTree = ""; }; + FABDA91B2552448200B5C523 /* b2_weld_joint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_weld_joint.cpp; sourceTree = ""; }; + FABDA91C2552448200B5C523 /* b2_chain_polygon_contact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_chain_polygon_contact.cpp; sourceTree = ""; }; + FABDA91D2552448200B5C523 /* b2_edge_circle_contact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_edge_circle_contact.h; sourceTree = ""; }; + FABDA91E2552448200B5C523 /* b2_body.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_body.cpp; sourceTree = ""; }; + FABDA91F2552448200B5C523 /* b2_contact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_contact.cpp; sourceTree = ""; }; + FABDA9202552448200B5C523 /* b2_revolute_joint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_revolute_joint.cpp; sourceTree = ""; }; + FABDA9212552448200B5C523 /* b2_contact_solver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_contact_solver.h; sourceTree = ""; }; + FABDA9222552448200B5C523 /* b2_contact_solver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_contact_solver.cpp; sourceTree = ""; }; + FABDA9232552448200B5C523 /* b2_world_callbacks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_world_callbacks.cpp; sourceTree = ""; }; + FABDA9242552448200B5C523 /* b2_pulley_joint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_pulley_joint.cpp; sourceTree = ""; }; + FABDA9252552448200B5C523 /* b2_polygon_circle_contact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_polygon_circle_contact.cpp; sourceTree = ""; }; + FABDA9262552448200B5C523 /* b2_edge_polygon_contact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_edge_polygon_contact.h; sourceTree = ""; }; + FABDA9272552448200B5C523 /* b2_distance_joint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_distance_joint.cpp; sourceTree = ""; }; + FABDA9282552448200B5C523 /* b2_contact_manager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_contact_manager.cpp; sourceTree = ""; }; + FABDA9292552448200B5C523 /* b2_polygon_contact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_polygon_contact.cpp; sourceTree = ""; }; + FABDA92A2552448200B5C523 /* b2_edge_polygon_contact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_edge_polygon_contact.cpp; sourceTree = ""; }; + FABDA92B2552448200B5C523 /* b2_edge_circle_contact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_edge_circle_contact.cpp; sourceTree = ""; }; + FABDA92C2552448200B5C523 /* b2_gear_joint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_gear_joint.cpp; sourceTree = ""; }; + FABDA92D2552448200B5C523 /* b2_friction_joint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_friction_joint.cpp; sourceTree = ""; }; + FABDA92E2552448200B5C523 /* b2_wheel_joint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_wheel_joint.cpp; sourceTree = ""; }; + FABDA92F2552448200B5C523 /* b2_polygon_contact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_polygon_contact.h; sourceTree = ""; }; + FABDA9302552448200B5C523 /* b2_motor_joint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_motor_joint.cpp; sourceTree = ""; }; + FABDA9312552448200B5C523 /* b2_rope_joint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_rope_joint.cpp; sourceTree = ""; }; + FABDA9322552448200B5C523 /* b2_world.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_world.cpp; sourceTree = ""; }; + FABDA9332552448200B5C523 /* b2_island.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_island.cpp; sourceTree = ""; }; + FABDA9342552448200B5C523 /* b2_mouse_joint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_mouse_joint.cpp; sourceTree = ""; }; + FABDA9352552448200B5C523 /* b2_circle_contact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_circle_contact.cpp; sourceTree = ""; }; + FABDA9362552448200B5C523 /* b2_prismatic_joint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_prismatic_joint.cpp; sourceTree = ""; }; + FABDA9372552448200B5C523 /* b2_fixture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_fixture.cpp; sourceTree = ""; }; + FABDA9382552448200B5C523 /* b2_island.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_island.h; sourceTree = ""; }; + FABDA9392552448200B5C523 /* b2_motor_joint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_motor_joint.h; sourceTree = ""; }; + FABDA93A2552448200B5C523 /* b2_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_common.h; sourceTree = ""; }; + FABDA93B2552448200B5C523 /* b2_weld_joint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_weld_joint.h; sourceTree = ""; }; + FABDA93C2552448200B5C523 /* b2_dynamic_tree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_dynamic_tree.h; sourceTree = ""; }; + FABDA93D2552448200B5C523 /* b2_fixture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_fixture.h; sourceTree = ""; }; + FABDA93E2552448200B5C523 /* b2_stack_allocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_stack_allocator.h; sourceTree = ""; }; + FABDA93F2552448200B5C523 /* Box2D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Box2D.h; sourceTree = ""; }; + FABDA9402552448200B5C523 /* b2_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_types.h; sourceTree = ""; }; + FABDA9412552448200B5C523 /* b2_broad_phase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_broad_phase.h; sourceTree = ""; }; + FABDA9432552448200B5C523 /* b2_rope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_rope.cpp; sourceTree = ""; }; + FABDA9442552448200B5C523 /* b2_settings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_settings.h; sourceTree = ""; }; + FABDA9452552448200B5C523 /* b2_revolute_joint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_revolute_joint.h; sourceTree = ""; }; + FABDA9462552448200B5C523 /* README.MODIFIED */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.MODIFIED; sourceTree = ""; }; + FABDA9472552448200B5C523 /* b2_rope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_rope.h; sourceTree = ""; }; + FABDA9482552448200B5C523 /* b2_distance_joint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_distance_joint.h; sourceTree = ""; }; + FABDA9492552448200B5C523 /* b2_body.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_body.h; sourceTree = ""; }; + FABDA94A2552448200B5C523 /* b2_distance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_distance.h; sourceTree = ""; }; + FABDA94B2552448200B5C523 /* b2_time_step.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_time_step.h; sourceTree = ""; }; + FABDA94C2552448200B5C523 /* b2_pulley_joint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_pulley_joint.h; sourceTree = ""; }; + FABDA94D2552448200B5C523 /* b2_circle_shape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_circle_shape.h; sourceTree = ""; }; + FABDA94E2552448200B5C523 /* b2_math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_math.h; sourceTree = ""; }; + FABDA94F2552448200B5C523 /* b2_time_of_impact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_time_of_impact.h; sourceTree = ""; }; + FABDA9502552448200B5C523 /* b2_mouse_joint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_mouse_joint.h; sourceTree = ""; }; + FABDA9522552448200B5C523 /* b2_draw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_draw.cpp; sourceTree = ""; }; + FABDA9532552448200B5C523 /* b2_timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_timer.cpp; sourceTree = ""; }; + FABDA9542552448200B5C523 /* b2_block_allocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_block_allocator.cpp; sourceTree = ""; }; + FABDA9552552448200B5C523 /* b2_stack_allocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_stack_allocator.cpp; sourceTree = ""; }; + FABDA9562552448200B5C523 /* b2_settings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_settings.cpp; sourceTree = ""; }; + FABDA9572552448200B5C523 /* b2_math.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_math.cpp; sourceTree = ""; }; + FABDA9582552448200B5C523 /* b2_friction_joint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_friction_joint.h; sourceTree = ""; }; + FABDA9592552448200B5C523 /* b2_contact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_contact.h; sourceTree = ""; }; + FABDA95A2552448200B5C523 /* b2_prismatic_joint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_prismatic_joint.h; sourceTree = ""; }; + FABDA95B2552448200B5C523 /* b2_world.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_world.h; sourceTree = ""; }; + FABDA95C2552448200B5C523 /* b2_polygon_shape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_polygon_shape.h; sourceTree = ""; }; + FABDA95D2552448200B5C523 /* b2_wheel_joint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_wheel_joint.h; sourceTree = ""; }; + FABDA95E2552448200B5C523 /* b2_growable_stack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_growable_stack.h; sourceTree = ""; }; + FABDA95F2552448200B5C523 /* b2_draw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_draw.h; sourceTree = ""; }; + FABDA9602552448200B5C523 /* b2_collision.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_collision.h; sourceTree = ""; }; + FABDA9612552448200B5C523 /* b2_rope_joint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_rope_joint.h; sourceTree = ""; }; + FABDA9622552448200B5C523 /* b2_api.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_api.h; sourceTree = ""; }; + FABDA9632552448200B5C523 /* b2_chain_shape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_chain_shape.h; sourceTree = ""; }; + FABDA9642552448200B5C523 /* b2_gear_joint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_gear_joint.h; sourceTree = ""; }; + FABDA9652552448200B5C523 /* b2_timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_timer.h; sourceTree = ""; }; + FABDA9662552448200B5C523 /* b2_world_callbacks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_world_callbacks.h; sourceTree = ""; }; + FABDA9682552448200B5C523 /* b2_collide_circle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_collide_circle.cpp; sourceTree = ""; }; + FABDA9692552448200B5C523 /* b2_circle_shape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_circle_shape.cpp; sourceTree = ""; }; + FABDA96A2552448200B5C523 /* b2_collision.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_collision.cpp; sourceTree = ""; }; + FABDA96B2552448200B5C523 /* b2_collide_edge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_collide_edge.cpp; sourceTree = ""; }; + FABDA96C2552448200B5C523 /* b2_chain_shape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_chain_shape.cpp; sourceTree = ""; }; + FABDA96D2552448200B5C523 /* b2_broad_phase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_broad_phase.cpp; sourceTree = ""; }; + FABDA96E2552448200B5C523 /* b2_dynamic_tree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_dynamic_tree.cpp; sourceTree = ""; }; + FABDA96F2552448200B5C523 /* b2_polygon_shape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_polygon_shape.cpp; sourceTree = ""; }; + FABDA9702552448200B5C523 /* b2_collide_polygon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_collide_polygon.cpp; sourceTree = ""; }; + FABDA9712552448200B5C523 /* b2_edge_shape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_edge_shape.cpp; sourceTree = ""; }; + FABDA9722552448200B5C523 /* b2_time_of_impact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_time_of_impact.cpp; sourceTree = ""; }; + FABDA9732552448200B5C523 /* b2_distance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_distance.cpp; sourceTree = ""; }; + FABDA9742552448200B5C523 /* b2_contact_manager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_contact_manager.h; sourceTree = ""; }; + FABDA9752552448200B5C523 /* b2_edge_shape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_edge_shape.h; sourceTree = ""; }; FAC271E323B5B5B400C200D3 /* renderstate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = renderstate.h; sourceTree = ""; }; FAC271E423B5B5B400C200D3 /* renderstate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = renderstate.cpp; sourceTree = ""; }; FAC734C11B2E021A00AB460A /* wrap_SoundData.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = wrap_SoundData.lua; sourceTree = ""; }; @@ -2245,7 +2253,7 @@ FA0B794D1A958EA3000E1D17 /* libraries */ = { isa = PBXGroup; children = ( - FA0B794E1A958EA3000E1D17 /* Box2D */, + FABDA9102552448200B5C523 /* box2d */, FA0B79B41A958EA3000E1D17 /* ddsparse */, FA522D5023F9FF2A0059EE3C /* dr */, FA0B79B81A958EA3000E1D17 /* enet */, @@ -2267,162 +2275,6 @@ path = ../../src/libraries; sourceTree = ""; }; - FA0B794E1A958EA3000E1D17 /* Box2D */ = { - isa = PBXGroup; - children = ( - FA0B794F1A958EA3000E1D17 /* Box2D.h */, - FA0B79501A958EA3000E1D17 /* Collision */, - FA0B79681A958EA3000E1D17 /* Common */, - FA0B79761A958EA3000E1D17 /* Dynamics */, - FA0B79B11A958EA3000E1D17 /* Rope */, - ); - path = Box2D; - sourceTree = ""; - }; - FA0B79501A958EA3000E1D17 /* Collision */ = { - isa = PBXGroup; - children = ( - FA0B79511A958EA3000E1D17 /* b2BroadPhase.cpp */, - FA0B79521A958EA3000E1D17 /* b2BroadPhase.h */, - FA0B79531A958EA3000E1D17 /* b2CollideCircle.cpp */, - FA0B79541A958EA3000E1D17 /* b2CollideEdge.cpp */, - FA0B79551A958EA3000E1D17 /* b2CollidePolygon.cpp */, - FA0B79561A958EA3000E1D17 /* b2Collision.cpp */, - FA0B79571A958EA3000E1D17 /* b2Collision.h */, - FA0B79581A958EA3000E1D17 /* b2Distance.cpp */, - FA0B79591A958EA3000E1D17 /* b2Distance.h */, - FA0B795A1A958EA3000E1D17 /* b2DynamicTree.cpp */, - FA0B795B1A958EA3000E1D17 /* b2DynamicTree.h */, - FA0B795C1A958EA3000E1D17 /* b2TimeOfImpact.cpp */, - FA0B795D1A958EA3000E1D17 /* b2TimeOfImpact.h */, - FA0B795E1A958EA3000E1D17 /* Shapes */, - ); - path = Collision; - sourceTree = ""; - }; - FA0B795E1A958EA3000E1D17 /* Shapes */ = { - isa = PBXGroup; - children = ( - FA0B795F1A958EA3000E1D17 /* b2ChainShape.cpp */, - FA0B79601A958EA3000E1D17 /* b2ChainShape.h */, - FA0B79611A958EA3000E1D17 /* b2CircleShape.cpp */, - FA0B79621A958EA3000E1D17 /* b2CircleShape.h */, - FA0B79631A958EA3000E1D17 /* b2EdgeShape.cpp */, - FA0B79641A958EA3000E1D17 /* b2EdgeShape.h */, - FA0B79651A958EA3000E1D17 /* b2PolygonShape.cpp */, - FA0B79661A958EA3000E1D17 /* b2PolygonShape.h */, - FA0B79671A958EA3000E1D17 /* b2Shape.h */, - ); - path = Shapes; - sourceTree = ""; - }; - FA0B79681A958EA3000E1D17 /* Common */ = { - isa = PBXGroup; - children = ( - FA0B79691A958EA3000E1D17 /* b2BlockAllocator.cpp */, - FA0B796A1A958EA3000E1D17 /* b2BlockAllocator.h */, - FA0B796B1A958EA3000E1D17 /* b2Draw.cpp */, - FA0B796C1A958EA3000E1D17 /* b2Draw.h */, - FA0B796D1A958EA3000E1D17 /* b2GrowableStack.h */, - FA0B796E1A958EA3000E1D17 /* b2Math.cpp */, - FA0B796F1A958EA3000E1D17 /* b2Math.h */, - FA0B79701A958EA3000E1D17 /* b2Settings.cpp */, - FA0B79711A958EA3000E1D17 /* b2Settings.h */, - FA0B79721A958EA3000E1D17 /* b2StackAllocator.cpp */, - FA0B79731A958EA3000E1D17 /* b2StackAllocator.h */, - FA0B79741A958EA3000E1D17 /* b2Timer.cpp */, - FA0B79751A958EA3000E1D17 /* b2Timer.h */, - ); - path = Common; - sourceTree = ""; - }; - FA0B79761A958EA3000E1D17 /* Dynamics */ = { - isa = PBXGroup; - children = ( - FA0B79771A958EA3000E1D17 /* b2Body.cpp */, - FA0B79781A958EA3000E1D17 /* b2Body.h */, - FA0B79791A958EA3000E1D17 /* b2ContactManager.cpp */, - FA0B797A1A958EA3000E1D17 /* b2ContactManager.h */, - FA0B797B1A958EA3000E1D17 /* b2Fixture.cpp */, - FA0B797C1A958EA3000E1D17 /* b2Fixture.h */, - FA0B797D1A958EA3000E1D17 /* b2Island.cpp */, - FA0B797E1A958EA3000E1D17 /* b2Island.h */, - FA0B797F1A958EA3000E1D17 /* b2TimeStep.h */, - FA0B79801A958EA3000E1D17 /* b2World.cpp */, - FA0B79811A958EA3000E1D17 /* b2World.h */, - FA0B79821A958EA3000E1D17 /* b2WorldCallbacks.cpp */, - FA0B79831A958EA3000E1D17 /* b2WorldCallbacks.h */, - FA0B79841A958EA3000E1D17 /* Contacts */, - FA0B79971A958EA3000E1D17 /* Joints */, - ); - path = Dynamics; - sourceTree = ""; - }; - FA0B79841A958EA3000E1D17 /* Contacts */ = { - isa = PBXGroup; - children = ( - FA0B79851A958EA3000E1D17 /* b2ChainAndCircleContact.cpp */, - FA0B79861A958EA3000E1D17 /* b2ChainAndCircleContact.h */, - FA0B79871A958EA3000E1D17 /* b2ChainAndPolygonContact.cpp */, - FA0B79881A958EA3000E1D17 /* b2ChainAndPolygonContact.h */, - FA0B79891A958EA3000E1D17 /* b2CircleContact.cpp */, - FA0B798A1A958EA3000E1D17 /* b2CircleContact.h */, - FA0B798B1A958EA3000E1D17 /* b2Contact.cpp */, - FA0B798C1A958EA3000E1D17 /* b2Contact.h */, - FA0B798D1A958EA3000E1D17 /* b2ContactSolver.cpp */, - FA0B798E1A958EA3000E1D17 /* b2ContactSolver.h */, - FA0B798F1A958EA3000E1D17 /* b2EdgeAndCircleContact.cpp */, - FA0B79901A958EA3000E1D17 /* b2EdgeAndCircleContact.h */, - FA0B79911A958EA3000E1D17 /* b2EdgeAndPolygonContact.cpp */, - FA0B79921A958EA3000E1D17 /* b2EdgeAndPolygonContact.h */, - FA0B79931A958EA3000E1D17 /* b2PolygonAndCircleContact.cpp */, - FA0B79941A958EA3000E1D17 /* b2PolygonAndCircleContact.h */, - FA0B79951A958EA3000E1D17 /* b2PolygonContact.cpp */, - FA0B79961A958EA3000E1D17 /* b2PolygonContact.h */, - ); - path = Contacts; - sourceTree = ""; - }; - FA0B79971A958EA3000E1D17 /* Joints */ = { - isa = PBXGroup; - children = ( - FA0B79981A958EA3000E1D17 /* b2DistanceJoint.cpp */, - FA0B79991A958EA3000E1D17 /* b2DistanceJoint.h */, - FA0B799A1A958EA3000E1D17 /* b2FrictionJoint.cpp */, - FA0B799B1A958EA3000E1D17 /* b2FrictionJoint.h */, - FA0B799C1A958EA3000E1D17 /* b2GearJoint.cpp */, - FA0B799D1A958EA3000E1D17 /* b2GearJoint.h */, - FA0B799E1A958EA3000E1D17 /* b2Joint.cpp */, - FA0B799F1A958EA3000E1D17 /* b2Joint.h */, - FA0B79A01A958EA3000E1D17 /* b2MotorJoint.cpp */, - FA0B79A11A958EA3000E1D17 /* b2MotorJoint.h */, - FA0B79A21A958EA3000E1D17 /* b2MouseJoint.cpp */, - FA0B79A31A958EA3000E1D17 /* b2MouseJoint.h */, - FA0B79A41A958EA3000E1D17 /* b2PrismaticJoint.cpp */, - FA0B79A51A958EA3000E1D17 /* b2PrismaticJoint.h */, - FA0B79A61A958EA3000E1D17 /* b2PulleyJoint.cpp */, - FA0B79A71A958EA3000E1D17 /* b2PulleyJoint.h */, - FA0B79A81A958EA3000E1D17 /* b2RevoluteJoint.cpp */, - FA0B79A91A958EA3000E1D17 /* b2RevoluteJoint.h */, - FA0B79AA1A958EA3000E1D17 /* b2RopeJoint.cpp */, - FA0B79AB1A958EA3000E1D17 /* b2RopeJoint.h */, - FA0B79AC1A958EA3000E1D17 /* b2WeldJoint.cpp */, - FA0B79AD1A958EA3000E1D17 /* b2WeldJoint.h */, - FA0B79AE1A958EA3000E1D17 /* b2WheelJoint.cpp */, - FA0B79AF1A958EA3000E1D17 /* b2WheelJoint.h */, - ); - path = Joints; - sourceTree = ""; - }; - FA0B79B11A958EA3000E1D17 /* Rope */ = { - isa = PBXGroup; - children = ( - FA0B79B21A958EA3000E1D17 /* b2Rope.cpp */, - FA0B79B31A958EA3000E1D17 /* b2Rope.h */, - ); - path = Rope; - sourceTree = ""; - }; FA0B79B41A958EA3000E1D17 /* ddsparse */ = { isa = PBXGroup; children = ( @@ -3511,6 +3363,142 @@ path = lz4; sourceTree = ""; }; + FABDA9102552448200B5C523 /* box2d */ = { + isa = PBXGroup; + children = ( + FABDA9622552448200B5C523 /* b2_api.h */, + FABDA9132552448200B5C523 /* b2_block_allocator.h */, + FABDA9492552448200B5C523 /* b2_body.h */, + FABDA9412552448200B5C523 /* b2_broad_phase.h */, + FABDA9632552448200B5C523 /* b2_chain_shape.h */, + FABDA94D2552448200B5C523 /* b2_circle_shape.h */, + FABDA9602552448200B5C523 /* b2_collision.h */, + FABDA93A2552448200B5C523 /* b2_common.h */, + FABDA9742552448200B5C523 /* b2_contact_manager.h */, + FABDA9592552448200B5C523 /* b2_contact.h */, + FABDA9482552448200B5C523 /* b2_distance_joint.h */, + FABDA94A2552448200B5C523 /* b2_distance.h */, + FABDA95F2552448200B5C523 /* b2_draw.h */, + FABDA93C2552448200B5C523 /* b2_dynamic_tree.h */, + FABDA9752552448200B5C523 /* b2_edge_shape.h */, + FABDA93D2552448200B5C523 /* b2_fixture.h */, + FABDA9582552448200B5C523 /* b2_friction_joint.h */, + FABDA9642552448200B5C523 /* b2_gear_joint.h */, + FABDA95E2552448200B5C523 /* b2_growable_stack.h */, + FABDA9112552448200B5C523 /* b2_joint.h */, + FABDA94E2552448200B5C523 /* b2_math.h */, + FABDA9392552448200B5C523 /* b2_motor_joint.h */, + FABDA9502552448200B5C523 /* b2_mouse_joint.h */, + FABDA95C2552448200B5C523 /* b2_polygon_shape.h */, + FABDA95A2552448200B5C523 /* b2_prismatic_joint.h */, + FABDA94C2552448200B5C523 /* b2_pulley_joint.h */, + FABDA9452552448200B5C523 /* b2_revolute_joint.h */, + FABDA9612552448200B5C523 /* b2_rope_joint.h */, + FABDA9472552448200B5C523 /* b2_rope.h */, + FABDA9442552448200B5C523 /* b2_settings.h */, + FABDA9122552448200B5C523 /* b2_shape.h */, + FABDA93E2552448200B5C523 /* b2_stack_allocator.h */, + FABDA94F2552448200B5C523 /* b2_time_of_impact.h */, + FABDA94B2552448200B5C523 /* b2_time_step.h */, + FABDA9652552448200B5C523 /* b2_timer.h */, + FABDA9402552448200B5C523 /* b2_types.h */, + FABDA93B2552448200B5C523 /* b2_weld_joint.h */, + FABDA95D2552448200B5C523 /* b2_wheel_joint.h */, + FABDA9662552448200B5C523 /* b2_world_callbacks.h */, + FABDA95B2552448200B5C523 /* b2_world.h */, + FABDA93F2552448200B5C523 /* Box2D.h */, + FABDA9672552448200B5C523 /* collision */, + FABDA9512552448200B5C523 /* common */, + FABDA9142552448200B5C523 /* dynamics */, + FABDA9462552448200B5C523 /* README.MODIFIED */, + FABDA9422552448200B5C523 /* rope */, + ); + path = box2d; + sourceTree = ""; + }; + FABDA9142552448200B5C523 /* dynamics */ = { + isa = PBXGroup; + children = ( + FABDA91E2552448200B5C523 /* b2_body.cpp */, + FABDA9172552448200B5C523 /* b2_chain_circle_contact.cpp */, + FABDA9182552448200B5C523 /* b2_chain_circle_contact.h */, + FABDA91C2552448200B5C523 /* b2_chain_polygon_contact.cpp */, + FABDA9162552448200B5C523 /* b2_chain_polygon_contact.h */, + FABDA9352552448200B5C523 /* b2_circle_contact.cpp */, + FABDA91A2552448200B5C523 /* b2_circle_contact.h */, + FABDA9282552448200B5C523 /* b2_contact_manager.cpp */, + FABDA9222552448200B5C523 /* b2_contact_solver.cpp */, + FABDA9212552448200B5C523 /* b2_contact_solver.h */, + FABDA91F2552448200B5C523 /* b2_contact.cpp */, + FABDA9272552448200B5C523 /* b2_distance_joint.cpp */, + FABDA92B2552448200B5C523 /* b2_edge_circle_contact.cpp */, + FABDA91D2552448200B5C523 /* b2_edge_circle_contact.h */, + FABDA92A2552448200B5C523 /* b2_edge_polygon_contact.cpp */, + FABDA9262552448200B5C523 /* b2_edge_polygon_contact.h */, + FABDA9372552448200B5C523 /* b2_fixture.cpp */, + FABDA92D2552448200B5C523 /* b2_friction_joint.cpp */, + FABDA92C2552448200B5C523 /* b2_gear_joint.cpp */, + FABDA9332552448200B5C523 /* b2_island.cpp */, + FABDA9382552448200B5C523 /* b2_island.h */, + FABDA9152552448200B5C523 /* b2_joint.cpp */, + FABDA9302552448200B5C523 /* b2_motor_joint.cpp */, + FABDA9342552448200B5C523 /* b2_mouse_joint.cpp */, + FABDA9252552448200B5C523 /* b2_polygon_circle_contact.cpp */, + FABDA9192552448200B5C523 /* b2_polygon_circle_contact.h */, + FABDA9292552448200B5C523 /* b2_polygon_contact.cpp */, + FABDA92F2552448200B5C523 /* b2_polygon_contact.h */, + FABDA9362552448200B5C523 /* b2_prismatic_joint.cpp */, + FABDA9242552448200B5C523 /* b2_pulley_joint.cpp */, + FABDA9202552448200B5C523 /* b2_revolute_joint.cpp */, + FABDA9312552448200B5C523 /* b2_rope_joint.cpp */, + FABDA91B2552448200B5C523 /* b2_weld_joint.cpp */, + FABDA92E2552448200B5C523 /* b2_wheel_joint.cpp */, + FABDA9232552448200B5C523 /* b2_world_callbacks.cpp */, + FABDA9322552448200B5C523 /* b2_world.cpp */, + ); + path = dynamics; + sourceTree = ""; + }; + FABDA9422552448200B5C523 /* rope */ = { + isa = PBXGroup; + children = ( + FABDA9432552448200B5C523 /* b2_rope.cpp */, + ); + path = rope; + sourceTree = ""; + }; + FABDA9512552448200B5C523 /* common */ = { + isa = PBXGroup; + children = ( + FABDA9542552448200B5C523 /* b2_block_allocator.cpp */, + FABDA9522552448200B5C523 /* b2_draw.cpp */, + FABDA9572552448200B5C523 /* b2_math.cpp */, + FABDA9562552448200B5C523 /* b2_settings.cpp */, + FABDA9552552448200B5C523 /* b2_stack_allocator.cpp */, + FABDA9532552448200B5C523 /* b2_timer.cpp */, + ); + path = common; + sourceTree = ""; + }; + FABDA9672552448200B5C523 /* collision */ = { + isa = PBXGroup; + children = ( + FABDA96D2552448200B5C523 /* b2_broad_phase.cpp */, + FABDA96C2552448200B5C523 /* b2_chain_shape.cpp */, + FABDA9692552448200B5C523 /* b2_circle_shape.cpp */, + FABDA9682552448200B5C523 /* b2_collide_circle.cpp */, + FABDA96B2552448200B5C523 /* b2_collide_edge.cpp */, + FABDA9702552448200B5C523 /* b2_collide_polygon.cpp */, + FABDA96A2552448200B5C523 /* b2_collision.cpp */, + FABDA9732552448200B5C523 /* b2_distance.cpp */, + FABDA96E2552448200B5C523 /* b2_dynamic_tree.cpp */, + FABDA9712552448200B5C523 /* b2_edge_shape.cpp */, + FABDA96F2552448200B5C523 /* b2_polygon_shape.cpp */, + FABDA9722552448200B5C523 /* b2_time_of_impact.cpp */, + ); + path = collision; + sourceTree = ""; + }; FAC7CD591FE35E95006A60C7 /* physfs */ = { isa = PBXGroup; children = ( @@ -3775,6 +3763,7 @@ FA1557C41CE90BD200AFF582 /* EXRHandler.h in Headers */, FA0B7DC91A95902C000E1D17 /* Keyboard.h in Headers */, FA0B7D4A1A95902C000E1D17 /* Polyline.h in Headers */, + FABDA9E72552448300B5C523 /* b2_chain_shape.h in Headers */, FAF1405C1E20934C00F898D2 /* InitializeGlobals.h in Headers */, FA0B7DB31A95902C000E1D17 /* wrap_Image.h in Headers */, FAF140591E20934C00F898D2 /* Common.h in Headers */, @@ -3788,6 +3777,7 @@ FA0B79481A958E3B000E1D17 /* Vector.h in Headers */, FA0B7CCF1A95902C000E1D17 /* Audio.h in Headers */, FA0B7EC01A95902C000E1D17 /* Thread.h in Headers */, + FABDA9E12552448300B5C523 /* b2_wheel_joint.h in Headers */, FA0B7E9C1A95902C000E1D17 /* VorbisDecoder.h in Headers */, FAC271E523B5B5B400C200D3 /* renderstate.h in Headers */, FAC756FB1E4F99D200B91289 /* Effect.h in Headers */, @@ -3807,6 +3797,7 @@ FA0B7CDE1A95902C000E1D17 /* Source.h in Headers */, FA0B7E141A95902C000E1D17 /* GearJoint.h in Headers */, FAAA3FDA1F64B3AD00F89E99 /* lstrlib.h in Headers */, + FABDA98C2552448300B5C523 /* b2_contact_solver.h in Headers */, FA0B7E9F1A95902C000E1D17 /* WaveDecoder.h in Headers */, FAF140871E20934C00F898D2 /* parseVersions.h in Headers */, FA0B7AC61A958EA3000E1D17 /* types.h in Headers */, @@ -3816,27 +3807,29 @@ FA0B7EE41A95902D000E1D17 /* Window.h in Headers */, FA0B7CFC1A95902C000E1D17 /* Filesystem.h in Headers */, FA0B7AD81A958EA3000E1D17 /* lua-enet.h in Headers */, - FA0B7A3A1A958EA3000E1D17 /* b2DynamicTree.h in Headers */, FA0B7EBA1A95902C000E1D17 /* Channel.h in Headers */, FA0B7D3E1A95902C000E1D17 /* Texture.h in Headers */, FA0B7ECA1A95902C000E1D17 /* threads.h in Headers */, FADF54361E3DAE6E00012CC0 /* wrap_SpriteBatch.h in Headers */, FA0B7DB01A95902C000E1D17 /* wrap_CompressedImageData.h in Headers */, FAC7CD8D1FE35E95006A60C7 /* physfs_platforms.h in Headers */, + FABDA9B82552448300B5C523 /* b2_motor_joint.h in Headers */, FA0B7AC11A958EA3000E1D17 /* callbacks.h in Headers */, FA3C5E491F8D80CA0003C579 /* ShaderStage.h in Headers */, FA0B7D8F1A95902C000E1D17 /* ddsHandler.h in Headers */, FAB2D5AC1AABDD8A008224A4 /* TrueTypeRasterizer.h in Headers */, + FABDAA042552448300B5C523 /* b2_edge_shape.h in Headers */, FAF140C41E20934C00F898D2 /* ShaderLang.h in Headers */, FA1E887F1DF363CD00E808AA /* Filter.h in Headers */, FA27B3C21B4985BF008A9DCE /* wrap_VideoStream.h in Headers */, - FA0B7AA31A958EA3000E1D17 /* b2PulleyJoint.h in Headers */, FAF140621E20934C00F898D2 /* ShHandle.h in Headers */, FA0B7B2F1A958EA3000E1D17 /* utf8.h in Headers */, FA0B79231A958E3B000E1D17 /* EnumMap.h in Headers */, FAF140571E20934C00F898D2 /* arrays.h in Headers */, - FA0B7A371A958EA3000E1D17 /* b2Distance.h in Headers */, FA0B7E681A95902C000E1D17 /* wrap_PrismaticJoint.h in Headers */, + FABDA9DC2552448300B5C523 /* b2_friction_joint.h in Headers */, + FABDA9CA2552448300B5C523 /* b2_time_step.h in Headers */, + FABDA9CC2552448300B5C523 /* b2_circle_shape.h in Headers */, FA0B7D571A95902C000E1D17 /* Buffer.h in Headers */, FAF140AB1E20934C00F898D2 /* SymbolTable.h in Headers */, FA0B7ED71A95902D000E1D17 /* Timer.h in Headers */, @@ -3844,6 +3837,7 @@ FA0B7B2D1A958EA3000E1D17 /* core.h in Headers */, FA1E88841DF363DB00E808AA /* Filter.h in Headers */, 217DFC061D9F6D490055D849 /* tp.lua.h in Headers */, + FABDA9E02552448300B5C523 /* b2_polygon_shape.h in Headers */, FAB17BF71ABFC4B100F9BA27 /* lz4hc.h in Headers */, FA0B7E831A95902C000E1D17 /* Shape.h in Headers */, FAE272531C05A15B00A67640 /* ParticleSystem.h in Headers */, @@ -3857,28 +3851,27 @@ FA0B7EDE1A95902D000E1D17 /* Touch.h in Headers */, FAC7CD861FE35E95006A60C7 /* physfs.h in Headers */, FAF6C9E523C2DE2900D7B5BC /* spirv.hpp in Headers */, - FA0B7A541A958EA3000E1D17 /* b2Math.h in Headers */, FA522D4F23F9FE380059EE3C /* MP3Decoder.h in Headers */, 217DFBEE1D9F6D490055D849 /* luasocket.h in Headers */, FACA02F31F5E396B0084B28F /* HashFunction.h in Headers */, FA0B7ED01A95902C000E1D17 /* wrap_LuaThread.h in Headers */, FAF6C9E923C2DE2900D7B5BC /* GLSL.ext.KHR.h in Headers */, FA0B7CE41A95902C000E1D17 /* wrap_Audio.h in Headers */, - FA0B7A7F1A958EA3000E1D17 /* b2ContactSolver.h in Headers */, FADF540F1E3D7CDD00012CC0 /* wrap_Video.h in Headers */, FAA54ACA1F91660400A8FA7B /* OggDemuxer.h in Headers */, FA0B79491A958E3B000E1D17 /* version.h in Headers */, FAF140581E20934C00F898D2 /* BaseTypes.h in Headers */, + FABDA9E32552448300B5C523 /* b2_draw.h in Headers */, FA0B7B2B1A958EA3000E1D17 /* stb_image.h in Headers */, FAF140AE1E20934C00F898D2 /* Versions.h in Headers */, FA0B7CD21A95902C000E1D17 /* Audio.h in Headers */, FA0B79421A958E3B000E1D17 /* utf8.h in Headers */, FA0B7D171A95902C000E1D17 /* Font.h in Headers */, FAECA1B41F3164700095D008 /* CompressedSlice.h in Headers */, - FA0B7A6D1A958EA3000E1D17 /* b2World.h in Headers */, FA0B7EAE1A95902C000E1D17 /* wrap_SoundData.h in Headers */, FA0B7CFF1A95902C000E1D17 /* File.h in Headers */, FA0B7AB41A958EA3000E1D17 /* ddsinfo.h in Headers */, + FABDA9C62552448300B5C523 /* b2_rope.h in Headers */, FA0B7DD21A95902C000E1D17 /* love.h in Headers */, FAC8E54523AC832A007B07C8 /* NativeFile.h in Headers */, FA6A2B6F1F5F845F0074C308 /* wrap_DataView.h in Headers */, @@ -3890,52 +3883,54 @@ FAC7CD8E1FE35E95006A60C7 /* physfs_lzmasdk.h in Headers */, FA0B7B391A958EA3000E1D17 /* wuff_internal.h in Headers */, FAC7CD771FE35E95006A60C7 /* physfs_internal.h in Headers */, - FA0B7A5A1A958EA3000E1D17 /* b2StackAllocator.h in Headers */, FA0B7D881A95902C000E1D17 /* ImageData.h in Headers */, - FA0B7A661A958EA3000E1D17 /* b2Fixture.h in Headers */, FAF6C9DA23C2DE2900D7B5BC /* SPVRemapper.h in Headers */, FA0B7EE11A95902D000E1D17 /* wrap_Touch.h in Headers */, FA9D8DDB1DEF8411002CD881 /* Stream.h in Headers */, - FA0B7AA91A958EA3000E1D17 /* b2RopeJoint.h in Headers */, FAF6C9E823C2DE2900D7B5BC /* GLSL.ext.EXT.h in Headers */, FACA02F71F5E396B0084B28F /* wrap_DataModule.h in Headers */, + FABDA9BE2552448300B5C523 /* Box2D.h in Headers */, FA56AA3A1FAFF02000A43D5F /* memory.h in Headers */, FA0B7E441A95902C000E1D17 /* wrap_CircleShape.h in Headers */, FA0B7EB41A95902C000E1D17 /* System.h in Headers */, FAF1405A1E20934C00F898D2 /* ConstantUnion.h in Headers */, + FABDA9782552448200B5C523 /* b2_block_allocator.h in Headers */, FAF140A51E20934C00F898D2 /* Scan.h in Headers */, + FABDA9C72552448300B5C523 /* b2_distance_joint.h in Headers */, FA0B7CE11A95902C000E1D17 /* Source.h in Headers */, + FABDA9C32552448300B5C523 /* b2_settings.h in Headers */, FA24348621D401CB00B8918A /* attribute.h in Headers */, + FABDA9C02552448300B5C523 /* b2_broad_phase.h in Headers */, FAF140901E20934C00F898D2 /* PpContext.h in Headers */, FA0B7E621A95902C000E1D17 /* wrap_Physics.h in Headers */, FA0B7DF01A95902C000E1D17 /* Mouse.h in Headers */, + FABDA9E62552448300B5C523 /* b2_api.h in Headers */, 217DFBDC1D9F6D490055D849 /* buffer.h in Headers */, FA0B7DAD1A95902C000E1D17 /* STBHandler.h in Headers */, + FABDA9BB2552448300B5C523 /* b2_dynamic_tree.h in Headers */, FA1BA0A41E16D97500AA2803 /* wrap_Font.h in Headers */, FA0B7DE11A95902C000E1D17 /* wrap_Math.h in Headers */, - FA0B7AAF1A958EA3000E1D17 /* b2WheelJoint.h in Headers */, FA0B7D1A1A95902C000E1D17 /* TrueTypeRasterizer.h in Headers */, FA0B7EA81A95902C000E1D17 /* wrap_Decoder.h in Headers */, FA0B7AC51A958EA3000E1D17 /* time.h in Headers */, FA0B793E1A958E3B000E1D17 /* StringMap.h in Headers */, FA0B793A1A958E3B000E1D17 /* Reference.h in Headers */, FACA02F51F5E396B0084B28F /* wrap_CompressedData.h in Headers */, + FABDA9DF2552448300B5C523 /* b2_world.h in Headers */, FA0B7DCC1A95902C000E1D17 /* Keyboard.h in Headers */, FA620A341AA2F8DB005DB4C2 /* wrap_Quad.h in Headers */, FA0B7EA51A95902C000E1D17 /* SoundData.h in Headers */, FADF54271E3DA5BA00012CC0 /* Mesh.h in Headers */, FAF1405E1E20934C00F898D2 /* PoolAlloc.h in Headers */, - FA0B7A821A958EA3000E1D17 /* b2EdgeAndCircleContact.h in Headers */, FA0B79341A958E3B000E1D17 /* Object.h in Headers */, 217DFBF11D9F6D490055D849 /* mbox.lua.h in Headers */, FA0B7CEA1A95902C000E1D17 /* Event.h in Headers */, FA0B7E351A95902C000E1D17 /* WeldJoint.h in Headers */, + FABDA9CB2552448300B5C523 /* b2_pulley_joint.h in Headers */, FA0B7E2F1A95902C000E1D17 /* RopeJoint.h in Headers */, FA0B7D141A95902C000E1D17 /* Font.h in Headers */, FA0B7E591A95902C000E1D17 /* wrap_Joint.h in Headers */, - FA0B7A631A958EA3000E1D17 /* b2ContactManager.h in Headers */, FA0B7E771A95902C000E1D17 /* wrap_WeldJoint.h in Headers */, - FA0B7A911A958EA3000E1D17 /* b2FrictionJoint.h in Headers */, FA18CEC723D3AE6800263725 /* wrap_Buffer.h in Headers */, FA0B7E291A95902C000E1D17 /* PulleyJoint.h in Headers */, FA6BDE5C1F31725300786805 /* Color.h in Headers */, @@ -3944,53 +3939,49 @@ FAB17BE81ABFAA9000F9BA27 /* lz4.h in Headers */, FA0B7E6B1A95902C000E1D17 /* wrap_PulleyJoint.h in Headers */, FA0B7E051A95902C000E1D17 /* Contact.h in Headers */, - FA0B7A691A958EA3000E1D17 /* b2Island.h in Headers */, FA4F2BE41DE6650600CA37D7 /* Transform.h in Headers */, FA0B7E0E1A95902C000E1D17 /* Fixture.h in Headers */, - FA0B7A401A958EA3000E1D17 /* b2ChainShape.h in Headers */, FA6A2B661F5F7B6B0074C308 /* wrap_Data.h in Headers */, 217DFBE81D9F6D490055D849 /* inet.h in Headers */, FADF53FA1E3C7ACD00012CC0 /* Buffer.h in Headers */, - FA0B7AA61A958EA3000E1D17 /* b2RevoluteJoint.h in Headers */, FA0B7EEA1A95902D000E1D17 /* wrap_Window.h in Headers */, FA1557C01CE90A2C00AFF582 /* tinyexr.h in Headers */, FA0B7E381A95902C000E1D17 /* WheelJoint.h in Headers */, FA0B7D851A95902C000E1D17 /* Image.h in Headers */, + FABDA9EA2552448300B5C523 /* b2_world_callbacks.h in Headers */, FA0B7E7D1A95902C000E1D17 /* wrap_World.h in Headers */, FA0B7EBD1A95902C000E1D17 /* LuaThread.h in Headers */, FADF53FF1E3D74F200012CC0 /* Text.h in Headers */, FA0B7DC01A95902C000E1D17 /* JoystickModule.h in Headers */, FA0B7E871A95902C000E1D17 /* CoreAudioDecoder.h in Headers */, FA0B7CD51A95902C000E1D17 /* Source.h in Headers */, - FA0B7A2B1A958EA3000E1D17 /* b2BroadPhase.h in Headers */, 217DFBFD1D9F6D490055D849 /* smtp.lua.h in Headers */, + FABDA9772552448200B5C523 /* b2_shape.h in Headers */, FA27B39F1B498151008A9DCE /* Video.h in Headers */, - FA0B7AAC1A958EA3000E1D17 /* b2WeldJoint.h in Headers */, 217DFC041D9F6D490055D849 /* timeout.h in Headers */, FA0B7E7A1A95902C000E1D17 /* wrap_WheelJoint.h in Headers */, - FA0B7A791A958EA3000E1D17 /* b2CircleContact.h in Headers */, FA0B7DD81A95902C000E1D17 /* MathModule.h in Headers */, - FA0B7A341A958EA3000E1D17 /* b2Collision.h in Headers */, 217DFBDA1D9F6D490055D849 /* auxiliar.h in Headers */, FA0B7EC71A95902C000E1D17 /* ThreadModule.h in Headers */, FA4F2BAD1DE1E37000CA37D7 /* RecordingDevice.h in Headers */, + FABDA9CE2552448300B5C523 /* b2_time_of_impact.h in Headers */, FA0B792B1A958E3B000E1D17 /* Matrix.h in Headers */, FA0B7DA41A95902C000E1D17 /* PKMHandler.h in Headers */, FAF6C9E423C2DE2900D7B5BC /* doc.h in Headers */, FA0B7AC81A958EA3000E1D17 /* utility.h in Headers */, 217DFC0E1D9F6D490055D849 /* unixudp.h in Headers */, + FABDA9BA2552448300B5C523 /* b2_weld_joint.h in Headers */, FA522D5323F9FF2A0059EE3C /* dr_mp3.h in Headers */, FA0B791F1A958E3B000E1D17 /* Data.h in Headers */, 217DFBE41D9F6D490055D849 /* headers.lua.h in Headers */, FA0B7D021A95902C000E1D17 /* Filesystem.h in Headers */, FA0B7E471A95902C000E1D17 /* wrap_Contact.h in Headers */, FA0B7E021A95902C000E1D17 /* CircleShape.h in Headers */, + FABDA9E92552448300B5C523 /* b2_timer.h in Headers */, FA0B7E111A95902C000E1D17 /* FrictionJoint.h in Headers */, FA0B7AE01A958EA3000E1D17 /* lodepng.h in Headers */, - FA0B7A4D1A958EA3000E1D17 /* b2BlockAllocator.h in Headers */, FA0B7ECD1A95902C000E1D17 /* wrap_Channel.h in Headers */, FAF140AF1E20934C00F898D2 /* osinclude.h in Headers */, - FA0B7A431A958EA3000E1D17 /* b2CircleShape.h in Headers */, FA93C4531F315B960087CCD4 /* FormatHandler.h in Headers */, FA0B7CD81A95902C000E1D17 /* Audio.h in Headers */, FA0B7CF61A95902C000E1D17 /* File.h in Headers */, @@ -4001,11 +3992,13 @@ FA0B79271A958E3B000E1D17 /* int.h in Headers */, FA0B7E531A95902C000E1D17 /* wrap_FrictionJoint.h in Headers */, FA0B7EB71A95902C000E1D17 /* wrap_System.h in Headers */, + FABDAA032552448300B5C523 /* b2_contact_manager.h in Headers */, FA27B3A91B498151008A9DCE /* Video.h in Headers */, FAAA3FD81F64B3AD00F89E99 /* lprefix.h in Headers */, FAF6C9F023C2DE2900D7B5BC /* GlslangToSpv.h in Headers */, FAF6C9F723C2DE2900D7B5BC /* Logger.h in Headers */, 217DFBFA1D9F6D490055D849 /* select.h in Headers */, + FABDA9BF2552448300B5C523 /* b2_types.h in Headers */, FA0B7DF61A95902C000E1D17 /* wrap_Mouse.h in Headers */, FAF140661E20934C00F898D2 /* gl_types.h in Headers */, FA0B7E801A95902C000E1D17 /* Joint.h in Headers */, @@ -4018,15 +4011,17 @@ FAF1405F1E20934C00F898D2 /* ResourceLimits.h in Headers */, FA0B7DDB1A95902C000E1D17 /* RandomGenerator.h in Headers */, FA0B7E841A95902C000E1D17 /* Decoder.h in Headers */, - FA0B7A601A958EA3000E1D17 /* b2Body.h in Headers */, FA0B7EAB1A95902C000E1D17 /* wrap_Sound.h in Headers */, FA0B7B2C1A958EA3000E1D17 /* checked.h in Headers */, + FABDA9A62552448300B5C523 /* b2_polygon_contact.h in Headers */, FA0B7D2A1A95902C000E1D17 /* wrap_GlyphData.h in Headers */, FACA02F11F5E396B0084B28F /* DataModule.h in Headers */, + FABDA9C82552448300B5C523 /* b2_body.h in Headers */, FA0B7E741A95902C000E1D17 /* wrap_Shape.h in Headers */, - FA0B7A5D1A958EA3000E1D17 /* b2Timer.h in Headers */, + FABDA9762552448200B5C523 /* b2_joint.h in Headers */, + FABDA9CD2552448300B5C523 /* b2_math.h in Headers */, + FABDA9C42552448300B5C523 /* b2_revolute_joint.h in Headers */, FA91DA8D1F377C3900C80E33 /* deprecation.h in Headers */, - FA0B7A4A1A958EA3000E1D17 /* b2Shape.h in Headers */, FAF1407F1E20934C00F898D2 /* localintermediate.h in Headers */, FAF1406B1E20934C00F898D2 /* glslang_tab.cpp.h in Headers */, 217DFBF71D9F6D490055D849 /* options.h in Headers */, @@ -4037,27 +4032,33 @@ FA4F2BE61DE6650600CA37D7 /* wrap_Transform.h in Headers */, FA0B7EE71A95902D000E1D17 /* Window.h in Headers */, FA0B7E651A95902C000E1D17 /* wrap_PolygonShape.h in Headers */, + FABDA9952552448300B5C523 /* b2_edge_polygon_contact.h in Headers */, FA0B7AC91A958EA3000E1D17 /* win32.h in Headers */, + FABDA9B92552448300B5C523 /* b2_common.h in Headers */, FA0B7DFC1A95902C000E1D17 /* Body.h in Headers */, FA1BA0B31E16FD0800AA2803 /* Shader.h in Headers */, FAF6C9F123C2DE2900D7B5BC /* GLSL.std.450.h in Headers */, + FABDA97E2552448200B5C523 /* b2_chain_circle_contact.h in Headers */, + FABDA9DD2552448300B5C523 /* b2_contact.h in Headers */, + FABDA9802552448200B5C523 /* b2_circle_contact.h in Headers */, 217DFC101D9F6D490055D849 /* url.lua.h in Headers */, FAF140DD1E20934C00F898D2 /* InitializeDll.h in Headers */, - FA0B7A941A958EA3000E1D17 /* b2GearJoint.h in Headers */, FA0B7DF31A95902C000E1D17 /* wrap_Cursor.h in Headers */, - FA0B7A461A958EA3000E1D17 /* b2EdgeShape.h in Headers */, FA0B7D271A95902C000E1D17 /* wrap_Font.h in Headers */, - FA0B7A761A958EA3000E1D17 /* b2ChainAndPolygonContact.h in Headers */, FA0B7DAA1A95902C000E1D17 /* PVRHandler.h in Headers */, FA27B3B51B498151008A9DCE /* wrap_Video.h in Headers */, + FABDA9BC2552448300B5C523 /* b2_fixture.h in Headers */, FA0B7D7B1A95902C000E1D17 /* Quad.h in Headers */, FA0B7E261A95902C000E1D17 /* PrismaticJoint.h in Headers */, + FABDA9852552448200B5C523 /* b2_edge_circle_contact.h in Headers */, FA0B7E991A95902C000E1D17 /* Sound.h in Headers */, FA0B7D841A95902C000E1D17 /* CompressedImageData.h in Headers */, FACA02ED1F5E396B0084B28F /* CompressedData.h in Headers */, FAF1407E1E20934C00F898D2 /* LiveTraverser.h in Headers */, FA0B7D231A95902C000E1D17 /* Rasterizer.h in Headers */, + FABDA9B72552448300B5C523 /* b2_island.h in Headers */, FAD19A191DFF8CA200D5398A /* ImageDataBase.h in Headers */, + FABDA9E22552448300B5C523 /* b2_growable_stack.h in Headers */, FA0B7CDB1A95902C000E1D17 /* Pool.h in Headers */, FA0B7D0B1A95902C000E1D17 /* wrap_FileData.h in Headers */, FA0B7DF91A95902C000E1D17 /* Body.h in Headers */, @@ -4073,36 +4074,31 @@ FA0B7DA71A95902C000E1D17 /* PNGHandler.h in Headers */, FA0B7AC41A958EA3000E1D17 /* protocol.h in Headers */, FAF140601E20934C00F898D2 /* revision.h in Headers */, + FABDA97F2552448200B5C523 /* b2_polygon_circle_contact.h in Headers */, FAF140A21E20934C00F898D2 /* RemoveTree.h in Headers */, FAF6C9DE23C2DE2900D7B5BC /* SpvTools.h in Headers */, - FA0B7A8E1A958EA3000E1D17 /* b2DistanceJoint.h in Headers */, - FA0B7A8B1A958EA3000E1D17 /* b2PolygonContact.h in Headers */, + FABDA9E82552448300B5C523 /* b2_gear_joint.h in Headers */, FA0B7D321A95902C000E1D17 /* Graphics.h in Headers */, FA0B7E321A95902C000E1D17 /* Shape.h in Headers */, FA620A371AA2F8DB005DB4C2 /* wrap_Texture.h in Headers */, FA0B7DBA1A95902C000E1D17 /* JoystickModule.h in Headers */, - FA0B7A731A958EA3000E1D17 /* b2ChainAndCircleContact.h in Headers */, - FA0B7AA01A958EA3000E1D17 /* b2PrismaticJoint.h in Headers */, FA0B7DEA1A95902C000E1D17 /* Mouse.h in Headers */, FA0B7E931A95902C000E1D17 /* ModPlugDecoder.h in Headers */, FA0B7D111A95902C000E1D17 /* BMFontRasterizer.h in Headers */, 217DFBE61D9F6D490055D849 /* http.lua.h in Headers */, FA0B7E3E1A95902C000E1D17 /* wrap_Body.h in Headers */, + FABDA9C92552448300B5C523 /* b2_distance.h in Headers */, FA24348921D401CB00B8918A /* pch.h in Headers */, FAF140991E20934C00F898D2 /* PpTokens.h in Headers */, - FA0B7A571A958EA3000E1D17 /* b2Settings.h in Headers */, FAF1405B1E20934C00F898D2 /* InfoSink.h in Headers */, FA0B7B321A958EA3000E1D17 /* wuff.h in Headers */, 217DFBF81D9F6D490055D849 /* pierror.h in Headers */, 217DFC021D9F6D490055D849 /* tcp.h in Headers */, - FA0B7A3D1A958EA3000E1D17 /* b2TimeOfImpact.h in Headers */, FA3C5E441F8C368C0003C579 /* ShaderStage.h in Headers */, FA0B79261A958E3B000E1D17 /* Exception.h in Headers */, FA0B7D4D1A95902C000E1D17 /* Shader.h in Headers */, FA0B793D1A958E3B000E1D17 /* runtime.h in Headers */, - FA0B7A701A958EA3000E1D17 /* b2WorldCallbacks.h in Headers */, FAF6C9E323C2DE2900D7B5BC /* GLSL.ext.AMD.h in Headers */, - FA0B7A9D1A958EA3000E1D17 /* b2MouseJoint.h in Headers */, FA57FB9A1AE1993600F2AD6D /* noise1234.h in Headers */, FACA02EF1F5E396B0084B28F /* Compressor.h in Headers */, FA0B7CED1A95902C000E1D17 /* Event.h in Headers */, @@ -4112,8 +4108,6 @@ FA0B79451A958E3B000E1D17 /* Variant.h in Headers */, FA0B7E5C1A95902C000E1D17 /* wrap_MotorJoint.h in Headers */, FA4F2BA91DE1E36400CA37D7 /* wrap_RecordingDevice.h in Headers */, - FA0B7A7C1A958EA3000E1D17 /* b2Contact.h in Headers */, - FA0B7A881A958EA3000E1D17 /* b2PolygonAndCircleContact.h in Headers */, FA4F2B7A1DE0125B00CA37D7 /* xxhash.h in Headers */, FA0B7DDE1A95902C000E1D17 /* wrap_BezierCurve.h in Headers */, FA0B7DED1A95902C000E1D17 /* Cursor.h in Headers */, @@ -4122,10 +4116,8 @@ FADF542C1E3DAADA00012CC0 /* wrap_Mesh.h in Headers */, FAA3A9B01B7D465A00CED060 /* android.h in Headers */, 217DFBDE1D9F6D490055D849 /* compat.h in Headers */, - FA0B7A491A958EA3000E1D17 /* b2PolygonShape.h in Headers */, FA0B79281A958E3B000E1D17 /* math.h in Headers */, 217DFC121D9F6D490055D849 /* usocket.h in Headers */, - FA0B7A9A1A958EA3000E1D17 /* b2MotorJoint.h in Headers */, 217DFC081D9F6D490055D849 /* udp.h in Headers */, FA0B7DCF1A95902C000E1D17 /* wrap_Keyboard.h in Headers */, FAF6C9DB23C2DE2900D7B5BC /* SpvBuilder.h in Headers */, @@ -4137,14 +4129,11 @@ FA0B7AC71A958EA3000E1D17 /* unix.h in Headers */, FA0B7E8D1A95902C000E1D17 /* FLACDecoder.h in Headers */, 217DFC001D9F6D490055D849 /* socket.lua.h in Headers */, - FA0B7A501A958EA3000E1D17 /* b2Draw.h in Headers */, FA0B7DE71A95902C000E1D17 /* Cursor.h in Headers */, 217DFBEC1D9F6D490055D849 /* ltn12.lua.h in Headers */, FA0B7DB61A95902C000E1D17 /* wrap_ImageData.h in Headers */, FADF543D1E3DAFF700012CC0 /* wrap_Graphics.h in Headers */, 217DFBFE1D9F6D490055D849 /* socket.h in Headers */, - FA0B7A971A958EA3000E1D17 /* b2Joint.h in Headers */, - FA0B7A851A958EA3000E1D17 /* b2EdgeAndPolygonContact.h in Headers */, FAF1409C1E20934C00F898D2 /* propagateNoContraction.h in Headers */, FA0B7D2D1A95902C000E1D17 /* wrap_Rasterizer.h in Headers */, FA0B7AB71A958EA3000E1D17 /* ddsparse.h in Headers */, @@ -4154,10 +4143,10 @@ 217DFBF51D9F6D490055D849 /* mime.lua.h in Headers */, FAC7CD961FE755B4006A60C7 /* lz4opt.h in Headers */, FA9D8DD31DEB56C3002CD881 /* pixelformat.h in Headers */, + FABDA9DE2552448300B5C523 /* b2_prismatic_joint.h in Headers */, FAF140A61E20934C00F898D2 /* ScanContext.h in Headers */, + FABDA97B2552448200B5C523 /* b2_chain_polygon_contact.h in Headers */, FA0B7E4A1A95902C000E1D17 /* wrap_DistanceJoint.h in Headers */, - FA0B7A6A1A958EA3000E1D17 /* b2TimeStep.h in Headers */, - FA0B7A281A958EA3000E1D17 /* Box2D.h in Headers */, FA0B7DE41A95902C000E1D17 /* wrap_RandomGenerator.h in Headers */, FAC8E55023B01C0D007B07C8 /* macos.h in Headers */, FA0B7E0B1A95902C000E1D17 /* EdgeShape.h in Headers */, @@ -4170,11 +4159,13 @@ FA0B7E411A95902C000E1D17 /* wrap_ChainShape.h in Headers */, FA0B7E171A95902C000E1D17 /* Joint.h in Headers */, FA0B793F1A958E3B000E1D17 /* types.h in Headers */, - FA0B7AB31A958EA3000E1D17 /* b2Rope.h in Headers */, + FABDA9BD2552448300B5C523 /* b2_stack_allocator.h in Headers */, + FABDA9CF2552448300B5C523 /* b2_mouse_joint.h in Headers */, + FABDA9E42552448300B5C523 /* b2_collision.h in Headers */, FA41A3CA1C0A1F950084430C /* ASTCHandler.h in Headers */, FADF54041E3D77B500012CC0 /* wrap_Text.h in Headers */, + FABDA9E52552448300B5C523 /* b2_rope_joint.h in Headers */, FA0B7ED31A95902C000E1D17 /* wrap_ThreadModule.h in Headers */, - FA0B7A511A958EA3000E1D17 /* b2GrowableStack.h in Headers */, FAC756F61E4F99B400B91289 /* Effect.h in Headers */, FA0B7ADD1A958EA3000E1D17 /* gladfuncs.hpp in Headers */, FAF1405D1E20934C00F898D2 /* intermediate.h in Headers */, @@ -4267,6 +4258,7 @@ 217DFBEB1D9F6D490055D849 /* ltn12.lua in Resources */, 217DFBF41D9F6D490055D849 /* mime.lua in Resources */, 217DFBE31D9F6D490055D849 /* headers.lua in Resources */, + FABDA9C52552448300B5C523 /* README.MODIFIED in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4285,13 +4277,13 @@ FA0B7D2C1A95902C000E1D17 /* wrap_Rasterizer.cpp in Sources */, FADF54081E3D78F700012CC0 /* Video.cpp in Sources */, FA9D8DD81DEF8411002CD881 /* Data.cpp in Sources */, + FABDA9992552448300B5C523 /* b2_contact_manager.cpp in Sources */, FA0B7E8F1A95902C000E1D17 /* GmeDecoder.cpp in Sources */, FADF542B1E3DAADA00012CC0 /* wrap_Mesh.cpp in Sources */, FA0B7CD71A95902C000E1D17 /* Audio.cpp in Sources */, FA0B7AC01A958EA3000E1D17 /* host.c in Sources */, FA0B7EB01A95902C000E1D17 /* System.cpp in Sources */, FA0B7EE31A95902D000E1D17 /* Window.cpp in Sources */, - FA0B7AAB1A958EA3000E1D17 /* b2WeldJoint.cpp in Sources */, FA0B7EC21A95902C000E1D17 /* threads.cpp in Sources */, FA4F2C051DE936C900CA37D7 /* compat.c in Sources */, FA4F2BE81DE6651000CA37D7 /* wrap_Transform.cpp in Sources */, @@ -4302,20 +4294,21 @@ FAE64A872071363100BC7981 /* physfs_archiver_slb.c in Sources */, FAF6C9E723C2DE2900D7B5BC /* SpvBuilder.cpp in Sources */, FA0B7DD11A95902C000E1D17 /* love.cpp in Sources */, + FABDA9B42552448300B5C523 /* b2_prismatic_joint.cpp in Sources */, FA15DFAF1F9B8D390042AB22 /* lstrlib.c in Sources */, FA0B7AB61A958EA3000E1D17 /* ddsparse.cpp in Sources */, + FABDA9F42552448300B5C523 /* b2_chain_shape.cpp in Sources */, FA0B7D221A95902C000E1D17 /* Rasterizer.cpp in Sources */, FAF6C9E223C2DE2900D7B5BC /* InReadableOrder.cpp in Sources */, - FA0B7A4F1A958EA3000E1D17 /* b2Draw.cpp in Sources */, FAF140BC1E20934C00F898D2 /* ossource.cpp in Sources */, FA0B7D7D1A95902C000E1D17 /* Texture.cpp in Sources */, FACA02FB1F5E397E0084B28F /* HashFunction.cpp in Sources */, FAF140A81E20934C00F898D2 /* ShaderLang.cpp in Sources */, FA1BA09E1E16CFCE00AA2803 /* Font.cpp in Sources */, + FABDA9A12552448300B5C523 /* b2_gear_joint.cpp in Sources */, FAE64A8A2071363100BC7981 /* physfs_archiver_wad.c in Sources */, FA0B7ECC1A95902C000E1D17 /* wrap_Channel.cpp in Sources */, FA0B7E6D1A95902C000E1D17 /* wrap_RevoluteJoint.cpp in Sources */, - FA0B7A5F1A958EA3000E1D17 /* b2Body.cpp in Sources */, FACA02FA1F5E397B0084B28F /* DataModule.cpp in Sources */, FA0B7E641A95902C000E1D17 /* wrap_PolygonShape.cpp in Sources */, FA4F2C031DE936C200CA37D7 /* auxiliar.c in Sources */, @@ -4323,81 +4316,85 @@ FA0B7CFE1A95902C000E1D17 /* File.cpp in Sources */, FA3C5E481F8D80CA0003C579 /* ShaderStage.cpp in Sources */, FA27B39E1B498151008A9DCE /* Video.cpp in Sources */, - FA0B7A751A958EA3000E1D17 /* b2ChainAndPolygonContact.cpp in Sources */, FA0B7E6A1A95902C000E1D17 /* wrap_PulleyJoint.cpp in Sources */, FA0B7DB81A95902C000E1D17 /* Joystick.cpp in Sources */, FA91DA8C1F377C3900C80E33 /* deprecation.cpp in Sources */, + FABDA9B02552448300B5C523 /* b2_mouse_joint.cpp in Sources */, FA6A2B6B1F5F7F560074C308 /* DataView.cpp in Sources */, FA0B7E401A95902C000E1D17 /* wrap_ChainShape.cpp in Sources */, + FABDA99F2552448300B5C523 /* b2_edge_circle_contact.cpp in Sources */, FA0B7DEC1A95902C000E1D17 /* Cursor.cpp in Sources */, FA0B7D871A95902C000E1D17 /* ImageData.cpp in Sources */, FA0B7E101A95902C000E1D17 /* FrictionJoint.cpp in Sources */, + FABDA9902552448300B5C523 /* b2_world_callbacks.cpp in Sources */, + FABDA9A52552448300B5C523 /* b2_wheel_joint.cpp in Sources */, FAF140741E20934C00F898D2 /* intermOut.cpp in Sources */, FA620A361AA2F8DB005DB4C2 /* wrap_Texture.cpp in Sources */, FA0B7D0A1A95902C000E1D17 /* wrap_FileData.cpp in Sources */, FAF140781E20934C00F898D2 /* iomapper.cpp in Sources */, FA0B7ABE1A958EA3000E1D17 /* compress.c in Sources */, + FABDA9AE2552448300B5C523 /* b2_island.cpp in Sources */, FA4F2C141DE936FE00CA37D7 /* usocket.c in Sources */, FAF140831E20934C00F898D2 /* ParseContextBase.cpp in Sources */, FA0B7AD21A958EA3000E1D17 /* protocol.c in Sources */, FAF140A41E20934C00F898D2 /* Scan.cpp in Sources */, FA0B7D1F1A95902C000E1D17 /* ImageRasterizer.cpp in Sources */, + FABDA9C22552448300B5C523 /* b2_rope.cpp in Sources */, FAE64A952071365100BC7981 /* physfs_platform_qnx.c in Sources */, + FABDA9FC2552448300B5C523 /* b2_collide_polygon.cpp in Sources */, + FABDA9D12552448300B5C523 /* b2_draw.cpp in Sources */, FA0B7EA41A95902C000E1D17 /* SoundData.cpp in Sources */, FAF1406A1E20934C00F898D2 /* glslang_tab.cpp in Sources */, FA8951A31AA2EDF300EC385A /* wrap_Event.cpp in Sources */, FADF540E1E3D7CDD00012CC0 /* wrap_Video.cpp in Sources */, - FA0B7A361A958EA3000E1D17 /* b2Distance.cpp in Sources */, FA0B7D4C1A95902C000E1D17 /* Shader.cpp in Sources */, FA0B792A1A958E3B000E1D17 /* Matrix.cpp in Sources */, FAF140981E20934C00F898D2 /* PpTokens.cpp in Sources */, FAF140AA1E20934C00F898D2 /* SymbolTable.cpp in Sources */, - FA0B7A8D1A958EA3000E1D17 /* b2DistanceJoint.cpp in Sources */, - FA0B7A841A958EA3000E1D17 /* b2EdgeAndPolygonContact.cpp in Sources */, + FABDA9892552448300B5C523 /* b2_contact.cpp in Sources */, FA3C5E431F8C368C0003C579 /* ShaderStage.cpp in Sources */, FA0B7E191A95902C000E1D17 /* MotorJoint.cpp in Sources */, FAF1406F1E20934C00F898D2 /* Initialize.cpp in Sources */, FA0B7E4F1A95902C000E1D17 /* wrap_Fixture.cpp in Sources */, FA0B7EBF1A95902C000E1D17 /* Thread.cpp in Sources */, FACA02F91F5E39790084B28F /* Compressor.cpp in Sources */, + FABDAA002552448300B5C523 /* b2_time_of_impact.cpp in Sources */, FAF140811E20934C00F898D2 /* parseConst.cpp in Sources */, FA4F2C121DE936FE00CA37D7 /* unixtcp.c in Sources */, FA0B7EB91A95902C000E1D17 /* Channel.cpp in Sources */, FAE64A962071365100BC7981 /* physfs_platform_windows.c in Sources */, FA4B66CA1ABBCF1900558F15 /* Timer.cpp in Sources */, - FA0B7A3F1A958EA3000E1D17 /* b2ChainShape.cpp in Sources */, FA0B7E921A95902C000E1D17 /* ModPlugDecoder.cpp in Sources */, FA0B7E521A95902C000E1D17 /* wrap_FrictionJoint.cpp in Sources */, FADF54351E3DAE6E00012CC0 /* wrap_SpriteBatch.cpp in Sources */, FA4F2BB51DE1E4C300CA37D7 /* wrap_RecordingDevice.cpp in Sources */, - FA0B7A311A958EA3000E1D17 /* b2CollidePolygon.cpp in Sources */, FA4F2C111DE936FE00CA37D7 /* unix.c in Sources */, FA1BA0A31E16D97500AA2803 /* wrap_Font.cpp in Sources */, - FA0B7A931A958EA3000E1D17 /* b2GearJoint.cpp in Sources */, + FABDA9842552448200B5C523 /* b2_chain_polygon_contact.cpp in Sources */, FA0B7E0D1A95902C000E1D17 /* Fixture.cpp in Sources */, FADF53FE1E3D74F200012CC0 /* Text.cpp in Sources */, FA0B7D191A95902C000E1D17 /* TrueTypeRasterizer.cpp in Sources */, FAC271E723B5B5B400C200D3 /* renderstate.cpp in Sources */, FA0B7CFB1A95902C000E1D17 /* Filesystem.cpp in Sources */, + FABDA9F82552448300B5C523 /* b2_dynamic_tree.cpp in Sources */, + FABDA98B2552448300B5C523 /* b2_revolute_joint.cpp in Sources */, FA0B7D3D1A95902C000E1D17 /* Texture.cpp in Sources */, FA0B7B351A958EA3000E1D17 /* wuff_convert.c in Sources */, FAF140941E20934C00F898D2 /* PpScanner.cpp in Sources */, + FABDA9EC2552448300B5C523 /* b2_collide_circle.cpp in Sources */, FA9D53AD1F5307E900125C6B /* Deprecations.cpp in Sources */, FA0B7E431A95902C000E1D17 /* wrap_CircleShape.cpp in Sources */, FAE64A912071364800BC7981 /* physfs.c in Sources */, FAE64A852071363100BC7981 /* physfs_archiver_mvl.c in Sources */, FA0B7CE61A95902C000E1D17 /* wrap_Source.cpp in Sources */, - FA0B7AA21A958EA3000E1D17 /* b2PulleyJoint.cpp in Sources */, FA9D8DDE1DEF842A002CD881 /* Drawable.cpp in Sources */, FA0B7CCE1A95902C000E1D17 /* Audio.cpp in Sources */, FADF54031E3D77B500012CC0 /* wrap_Text.cpp in Sources */, FA0B7DCB1A95902C000E1D17 /* Keyboard.cpp in Sources */, - FA0B7A901A958EA3000E1D17 /* b2FrictionJoint.cpp in Sources */, FA0B7DFB1A95902C000E1D17 /* Body.cpp in Sources */, FA0B7ED21A95902C000E1D17 /* wrap_ThreadModule.cpp in Sources */, FADF54261E3DA5BA00012CC0 /* Mesh.cpp in Sources */, FA0B7EE01A95902D000E1D17 /* wrap_Touch.cpp in Sources */, - FA0B7A3C1A958EA3000E1D17 /* b2TimeOfImpact.cpp in Sources */, FA4F2C081DE936DD00CA37D7 /* io.c in Sources */, FA0B7CDD1A95902C000E1D17 /* Source.cpp in Sources */, FAF6C9EC23C2DE2900D7B5BC /* GlslangToSpv.cpp in Sources */, @@ -4405,21 +4402,18 @@ FA0B7E701A95902C000E1D17 /* wrap_RopeJoint.cpp in Sources */, FA24348821D401CB00B8918A /* attribute.cpp in Sources */, FACA02FC1F5E39810084B28F /* wrap_CompressedData.cpp in Sources */, + FABDA9A32552448300B5C523 /* b2_friction_joint.cpp in Sources */, FAF140AD1E20934C00F898D2 /* Versions.cpp in Sources */, - FA0B7A7B1A958EA3000E1D17 /* b2Contact.cpp in Sources */, - FA0B7A6F1A958EA3000E1D17 /* b2WorldCallbacks.cpp in Sources */, FA0B793C1A958E3B000E1D17 /* runtime.cpp in Sources */, FAF140DC1E20934C00F898D2 /* InitializeDll.cpp in Sources */, FA0B7DBC1A95902C000E1D17 /* Joystick.cpp in Sources */, FA0B7DAF1A95902C000E1D17 /* wrap_CompressedImageData.cpp in Sources */, - FA0B7A481A958EA3000E1D17 /* b2PolygonShape.cpp in Sources */, - FA0B7A991A958EA3000E1D17 /* b2MotorJoint.cpp in Sources */, FA0B7AD51A958EA3000E1D17 /* unix.c in Sources */, FAB17BE71ABFAA9000F9BA27 /* lz4.c in Sources */, FAE64A902071364800BC7981 /* physfs_unicode.c in Sources */, FA4F2BE71DE6650D00CA37D7 /* Transform.cpp in Sources */, - FA0B7A531A958EA3000E1D17 /* b2Math.cpp in Sources */, FAF140A11E20934C00F898D2 /* RemoveTree.cpp in Sources */, + FABDA9972552448300B5C523 /* b2_distance_joint.cpp in Sources */, FA0B7CDA1A95902C000E1D17 /* Pool.cpp in Sources */, FA0B7E161A95902C000E1D17 /* Joint.cpp in Sources */, FA0B7EE91A95902D000E1D17 /* wrap_Window.cpp in Sources */, @@ -4427,7 +4421,7 @@ FA0B7AB91A958EA3000E1D17 /* enet.cpp in Sources */, FA0B7E281A95902C000E1D17 /* PulleyJoint.cpp in Sources */, FA56AA391FAFF02000A43D5F /* memory.cpp in Sources */, - FA0B7A4C1A958EA3000E1D17 /* b2BlockAllocator.cpp in Sources */, + FABDA98E2552448300B5C523 /* b2_contact_solver.cpp in Sources */, FAF1409E1E20934C00F898D2 /* reflection.cpp in Sources */, FA15DFAE1F9B8D360042AB22 /* lutf8lib.c in Sources */, FAF1408B1E20934C00F898D2 /* Pp.cpp in Sources */, @@ -4452,16 +4446,17 @@ FA0B7D801A95902C000E1D17 /* Volatile.cpp in Sources */, FA1BA0B21E16FD0800AA2803 /* Shader.cpp in Sources */, FA0B7EBC1A95902C000E1D17 /* LuaThread.cpp in Sources */, - FA0B7A871A958EA3000E1D17 /* b2PolygonAndCircleContact.cpp in Sources */, FA0B7EF21A959D2C000E1D17 /* ios.mm in Sources */, FAE64A802071362A00BC7981 /* physfs_archiver_7z.c in Sources */, + FABDA9942552448300B5C523 /* b2_polygon_circle_contact.cpp in Sources */, FA0B7D3A1A95902C000E1D17 /* Graphics.cpp in Sources */, FA4F2BB21DE1E4B400CA37D7 /* RecordingDevice.cpp in Sources */, FAE64A922071364B00BC7981 /* physfs_platform_winrt.cpp in Sources */, - FA0B7A2D1A958EA3000E1D17 /* b2CollideCircle.cpp in Sources */, + FABDA97A2552448200B5C523 /* b2_joint.cpp in Sources */, FA4F2C0F1DE936FE00CA37D7 /* timeout.c in Sources */, FA59A2D31C06481400328DBA /* ParticleSystem.cpp in Sources */, FA0B7E131A95902C000E1D17 /* GearJoint.cpp in Sources */, + FABDA99B2552448300B5C523 /* b2_polygon_contact.cpp in Sources */, FA0B7DC21A95902C000E1D17 /* wrap_Joystick.cpp in Sources */, FA0B7CD41A95902C000E1D17 /* Source.cpp in Sources */, FAA3A9AF1B7D465A00CED060 /* android.cpp in Sources */, @@ -4469,50 +4464,50 @@ FA0B7CD11A95902C000E1D17 /* Audio.cpp in Sources */, FA4F2B7B1DE0181B00CA37D7 /* xxhash.c in Sources */, FA0B7D131A95902C000E1D17 /* Font.cpp in Sources */, + FABDA9F62552448300B5C523 /* b2_broad_phase.cpp in Sources */, FA0B7EC91A95902C000E1D17 /* threads.cpp in Sources */, - FA0B7A781A958EA3000E1D17 /* b2CircleContact.cpp in Sources */, FAF1408D1E20934C00F898D2 /* PpAtom.cpp in Sources */, - FA0B7A9C1A958EA3000E1D17 /* b2MouseJoint.cpp in Sources */, + FABDA99D2552448300B5C523 /* b2_edge_polygon_contact.cpp in Sources */, FAF140721E20934C00F898D2 /* Intermediate.cpp in Sources */, FA41A3C91C0A1F950084430C /* ASTCHandler.cpp in Sources */, FA0B7E551A95902C000E1D17 /* wrap_GearJoint.cpp in Sources */, FA0B7E791A95902C000E1D17 /* wrap_WheelJoint.cpp in Sources */, + FABDA9AC2552448300B5C523 /* b2_world.cpp in Sources */, FA0B7DDD1A95902C000E1D17 /* wrap_BezierCurve.cpp in Sources */, - FA0B7A2A1A958EA3000E1D17 /* b2BroadPhase.cpp in Sources */, FA0A3A6123366CE9001C269E /* floattypes.cpp in Sources */, - FA0B7A811A958EA3000E1D17 /* b2EdgeAndCircleContact.cpp in Sources */, FA0B7D071A95902C000E1D17 /* wrap_File.cpp in Sources */, + FABDA9D52552448300B5C523 /* b2_block_allocator.cpp in Sources */, FA6A2B751F60B6710074C308 /* ByteData.cpp in Sources */, + FABDA9F02552448300B5C523 /* b2_collision.cpp in Sources */, FAD19A181DFF8CA200D5398A /* ImageDataBase.cpp in Sources */, FA0B7AD01A958EA3000E1D17 /* peer.c in Sources */, FA27B3C11B4985BF008A9DCE /* wrap_VideoStream.cpp in Sources */, FADF54211E3DA52C00012CC0 /* wrap_ParticleSystem.cpp in Sources */, FA0B791C1A958E3B000E1D17 /* b64.cpp in Sources */, FA1E88851DF363E100E808AA /* Filter.cpp in Sources */, + FABDA9DB2552448300B5C523 /* b2_math.cpp in Sources */, FA0B7DA01A95902C000E1D17 /* KTXHandler.cpp in Sources */, - FA0B7A5C1A958EA3000E1D17 /* b2Timer.cpp in Sources */, FA0B7CEC1A95902C000E1D17 /* Event.cpp in Sources */, FA27B3AB1B498151008A9DCE /* VideoStream.cpp in Sources */, - FA0B7A7E1A958EA3000E1D17 /* b2ContactSolver.cpp in Sources */, FA0B7E581A95902C000E1D17 /* wrap_Joint.cpp in Sources */, FAECA1B51F31648A0095D008 /* FormatHandler.cpp in Sources */, FA4F2C0A1DE936E600CA37D7 /* mime.c in Sources */, FA0B7E311A95902C000E1D17 /* Shape.cpp in Sources */, FA0B7E491A95902C000E1D17 /* wrap_DistanceJoint.cpp in Sources */, - FA0B7A391A958EA3000E1D17 /* b2DynamicTree.cpp in Sources */, FA4F2C101DE936FE00CA37D7 /* udp.c in Sources */, FAF6C9E023C2DE2900D7B5BC /* SpvTools.cpp in Sources */, FAE64A8F2071364200BC7981 /* physfs_platform_unix.c in Sources */, - FA0B7A681A958EA3000E1D17 /* b2Island.cpp in Sources */, FA18CEC623D3AE6800263725 /* wrap_Buffer.cpp in Sources */, FA0B7E2B1A95902C000E1D17 /* RevoluteJoint.cpp in Sources */, FA0B7B291A958EA3000E1D17 /* simplexnoise1234.cpp in Sources */, FA0B7D261A95902C000E1D17 /* wrap_Font.cpp in Sources */, FA4F2BB31DE1E4B800CA37D7 /* RecordingDevice.cpp in Sources */, + FABDA9A82552448300B5C523 /* b2_motor_joint.cpp in Sources */, FA4F2C071DE936DA00CA37D7 /* inet.c in Sources */, FAE64A8B2071363100BC7981 /* physfs_archiver_zip.c in Sources */, FA4F2C0B1DE936EA00CA37D7 /* options.c in Sources */, FA4F2C0D1DE936F100CA37D7 /* serial.c in Sources */, + FABDA9922552448300B5C523 /* b2_pulley_joint.cpp in Sources */, FA0B7E0A1A95902C000E1D17 /* EdgeShape.cpp in Sources */, FADF54301E3DABF600012CC0 /* SpriteBatch.cpp in Sources */, FA0B7CF81A95902C000E1D17 /* FileData.cpp in Sources */, @@ -4521,23 +4516,20 @@ FAE64A932071365100BC7981 /* physfs_platform_haiku.cpp in Sources */, FA0B7E981A95902C000E1D17 /* Sound.cpp in Sources */, FA0B7E371A95902C000E1D17 /* WheelJoint.cpp in Sources */, - FA0B7A8A1A958EA3000E1D17 /* b2PolygonContact.cpp in Sources */, FA4F2C0C1DE936ED00CA37D7 /* select.c in Sources */, + FABDA9AA2552448300B5C523 /* b2_rope_joint.cpp in Sources */, FA0B7D8E1A95902C000E1D17 /* ddsHandler.cpp in Sources */, FA0B7DFE1A95902C000E1D17 /* ChainShape.cpp in Sources */, FAE64A892071363100BC7981 /* physfs_archiver_vdf.c in Sources */, - FA0B7A451A958EA3000E1D17 /* b2EdgeShape.cpp in Sources */, FA15DFB21F9B8D840042AB22 /* TheoraVideoStream.cpp in Sources */, FAF1406D1E20934C00F898D2 /* InfoSink.cpp in Sources */, FAF1407B1E20934C00F898D2 /* limits.cpp in Sources */, FA0B7ABB1A958EA3000E1D17 /* callbacks.c in Sources */, - FA0B7A721A958EA3000E1D17 /* b2ChainAndCircleContact.cpp in Sources */, FA0B7EAA1A95902C000E1D17 /* wrap_Sound.cpp in Sources */, FA0B79391A958E3B000E1D17 /* Reference.cpp in Sources */, FA620A331AA2F8DB005DB4C2 /* wrap_Quad.cpp in Sources */, FA0B7E071A95902C000E1D17 /* DistanceJoint.cpp in Sources */, FADF543C1E3DAFF700012CC0 /* wrap_Graphics.cpp in Sources */, - FA0B7A331A958EA3000E1D17 /* b2Collision.cpp in Sources */, FAE64A942071365100BC7981 /* physfs_platform_os2.c in Sources */, FA0B7E5E1A95902C000E1D17 /* wrap_MouseJoint.cpp in Sources */, FA0B7B3B1A958EA3000E1D17 /* wuff_memory.c in Sources */, @@ -4546,29 +4538,27 @@ FA0B7ADF1A958EA3000E1D17 /* lodepng.cpp in Sources */, FAF140761E20934C00F898D2 /* IntermTraverse.cpp in Sources */, FA0B7E8C1A95902C000E1D17 /* FLACDecoder.cpp in Sources */, - FA0B7A421A958EA3000E1D17 /* b2CircleShape.cpp in Sources */, FA0B7D491A95902C000E1D17 /* Polyline.cpp in Sources */, FA0B7CE31A95902C000E1D17 /* wrap_Audio.cpp in Sources */, FA0B7B381A958EA3000E1D17 /* wuff_internal.c in Sources */, FA0B7DF81A95902C000E1D17 /* Body.cpp in Sources */, + FABDA9EE2552448300B5C523 /* b2_circle_shape.cpp in Sources */, FA4F2BB41DE1E4BD00CA37D7 /* RecordingDevice.cpp in Sources */, FA0B7DF51A95902C000E1D17 /* wrap_Mouse.cpp in Sources */, FA0B7E861A95902C000E1D17 /* CoreAudioDecoder.cpp in Sources */, FA0B7E761A95902C000E1D17 /* wrap_WeldJoint.cpp in Sources */, FA0B7D561A95902C000E1D17 /* Buffer.cpp in Sources */, - FA0B7A6C1A958EA3000E1D17 /* b2World.cpp in Sources */, FA1557C51CE90BD900AFF582 /* EXRHandler.cpp in Sources */, FA57FB991AE1993600F2AD6D /* noise1234.cpp in Sources */, FA0B7E221A95902C000E1D17 /* PolygonShape.cpp in Sources */, - FA0B7A651A958EA3000E1D17 /* b2Fixture.cpp in Sources */, FA28EBD61E352DB5003446F4 /* FenceSync.cpp in Sources */, FA0B7DA31A95902C000E1D17 /* PKMHandler.cpp in Sources */, - FA0B7AB21A958EA3000E1D17 /* b2Rope.cpp in Sources */, FAB17BF61ABFC4B100F9BA27 /* lz4hc.c in Sources */, FAF1408F1E20934C00F898D2 /* PpContext.cpp in Sources */, FA0B7EA71A95902C000E1D17 /* wrap_Decoder.cpp in Sources */, FA0B7E1C1A95902C000E1D17 /* MouseJoint.cpp in Sources */, FA29C0061E12355B00268CD8 /* StreamBuffer.cpp in Sources */, + FABDA9B62552448300B5C523 /* b2_fixture.cpp in Sources */, FAE64A882071363100BC7981 /* physfs_archiver_unpacked.c in Sources */, FA0B7CF51A95902C000E1D17 /* File.cpp in Sources */, FA0B7E341A95902C000E1D17 /* WeldJoint.cpp in Sources */, @@ -4581,21 +4571,24 @@ FA522D4E23F9FE380059EE3C /* MP3Decoder.cpp in Sources */, FA0B7D1C1A95902C000E1D17 /* GlyphData.cpp in Sources */, FA4F2C061DE936CD00CA37D7 /* except.c in Sources */, - FA0B7AAE1A958EA3000E1D17 /* b2WheelJoint.cpp in Sources */, + FABDA9B22552448300B5C523 /* b2_circle_contact.cpp in Sources */, + FABDA9822552448200B5C523 /* b2_weld_joint.cpp in Sources */, FA15DFB01F9B8D6A0042AB22 /* wrap_Data.cpp in Sources */, FA0B7E671A95902C000E1D17 /* wrap_PrismaticJoint.cpp in Sources */, FA0B7DCE1A95902C000E1D17 /* wrap_Keyboard.cpp in Sources */, + FABDA9D32552448300B5C523 /* b2_timer.cpp in Sources */, FA0B7EE61A95902D000E1D17 /* Window.cpp in Sources */, FA0B7E3A1A95902C000E1D17 /* World.cpp in Sources */, FA0B79471A958E3B000E1D17 /* Vector.cpp in Sources */, FAE64A832071363100BC7981 /* physfs_archiver_hog.c in Sources */, FAC756F71E4F99BC00B91289 /* Effect.cpp in Sources */, FA0B7E7F1A95902C000E1D17 /* Joint.cpp in Sources */, + FABDA9D92552448300B5C523 /* b2_settings.cpp in Sources */, FA0B7DB21A95902C000E1D17 /* wrap_Image.cpp in Sources */, FA0B7E891A95902C000E1D17 /* Decoder.cpp in Sources */, - FA0B7A591A958EA3000E1D17 /* b2StackAllocator.cpp in Sources */, FAECA1B31F3164700095D008 /* CompressedSlice.cpp in Sources */, FA0B7E3D1A95902C000E1D17 /* wrap_Body.cpp in Sources */, + FABDA9FE2552448300B5C523 /* b2_edge_shape.cpp in Sources */, FA0B7D7A1A95902C000E1D17 /* Quad.cpp in Sources */, FA620A3B1AA305F6005DB4C2 /* types.cpp in Sources */, FA0B7DD41A95902C000E1D17 /* BezierCurve.cpp in Sources */, @@ -4606,7 +4599,6 @@ FAF6C9DD23C2DE2900D7B5BC /* SpvPostProcess.cpp in Sources */, FA0B7DBF1A95902C000E1D17 /* JoystickModule.cpp in Sources */, FAB2D5AB1AABDD8A008224A4 /* TrueTypeRasterizer.cpp in Sources */, - FA0B7A9F1A958EA3000E1D17 /* b2PrismaticJoint.cpp in Sources */, FAF6C9FB23C2DE2900D7B5BC /* disassemble.cpp in Sources */, FAE64A822071363100BC7981 /* physfs_archiver_grp.c in Sources */, FAF6C9F323C2DE2900D7B5BC /* SPVRemapper.cpp in Sources */, @@ -4621,27 +4613,24 @@ FA0B7E9B1A95902C000E1D17 /* VorbisDecoder.cpp in Sources */, FA0B7E4C1A95902C000E1D17 /* wrap_EdgeShape.cpp in Sources */, FA0B7E251A95902C000E1D17 /* PrismaticJoint.cpp in Sources */, - FA0B7A561A958EA3000E1D17 /* b2Settings.cpp in Sources */, FA0B7E611A95902C000E1D17 /* wrap_Physics.cpp in Sources */, FA4F2C041DE936C600CA37D7 /* buffer.c in Sources */, FA0B7DC81A95902C000E1D17 /* Keyboard.cpp in Sources */, FA0B7EAD1A95902C000E1D17 /* wrap_SoundData.cpp in Sources */, FA0B7E2E1A95902C000E1D17 /* RopeJoint.cpp in Sources */, + FABDA9F22552448300B5C523 /* b2_collide_edge.cpp in Sources */, FA0B7CE01A95902C000E1D17 /* Source.cpp in Sources */, FA0B7ECF1A95902C000E1D17 /* wrap_LuaThread.cpp in Sources */, - FA0B7AA51A958EA3000E1D17 /* b2RevoluteJoint.cpp in Sources */, FA0B7EA11A95902C000E1D17 /* Sound.cpp in Sources */, FA0B7DE61A95902C000E1D17 /* Cursor.cpp in Sources */, FA6A2B711F5F845F0074C308 /* wrap_DataView.cpp in Sources */, FA0B7EDC1A95902D000E1D17 /* Touch.cpp in Sources */, FA0B7CE91A95902C000E1D17 /* Event.cpp in Sources */, FA4F2C131DE936FE00CA37D7 /* unixudp.c in Sources */, + FABDA97D2552448200B5C523 /* b2_chain_circle_contact.cpp in Sources */, FA9D8DE11DEF843D002CD881 /* Image.cpp in Sources */, - FA0B7A961A958EA3000E1D17 /* b2Joint.cpp in Sources */, - FA0B7A621A958EA3000E1D17 /* b2ContactManager.cpp in Sources */, FAC8E54723AC832A007B07C8 /* NativeFile.cpp in Sources */, FA15DFAD1F9B8CBA0042AB22 /* StringMap.cpp in Sources */, - FA0B7A2F1A958EA3000E1D17 /* b2CollideEdge.cpp in Sources */, FACA02F81F5E39760084B28F /* CompressedData.cpp in Sources */, FA0B7ADA1A958EA3000E1D17 /* glad.cpp in Sources */, FAF140541E20934C00F898D2 /* CodeGen.cpp in Sources */, @@ -4649,13 +4638,16 @@ FA6A2B7B1F60B8250074C308 /* wrap_ByteData.cpp in Sources */, FA0B7E821A95902C000E1D17 /* Shape.cpp in Sources */, FA0B7ACE1A958EA3000E1D17 /* packet.c in Sources */, + FABDA9872552448200B5C523 /* b2_body.cpp in Sources */, FAF140891E20934C00F898D2 /* PoolAlloc.cpp in Sources */, + FABDA9FA2552448300B5C523 /* b2_polygon_shape.cpp in Sources */, FA27B3B41B498151008A9DCE /* wrap_Video.cpp in Sources */, FA1E88801DF363D400E808AA /* Filter.cpp in Sources */, - FA0B7AA81A958EA3000E1D17 /* b2RopeJoint.cpp in Sources */, + FABDAA022552448300B5C523 /* b2_distance.cpp in Sources */, FA0B7ACC1A958EA3000E1D17 /* list.c in Sources */, FACA02FD1F5E39840084B28F /* wrap_DataModule.cpp in Sources */, FA0B7DEF1A95902C000E1D17 /* Mouse.cpp in Sources */, + FABDA9D72552448300B5C523 /* b2_stack_allocator.cpp in Sources */, FA0B79251A958E3B000E1D17 /* Exception.cpp in Sources */, FA0B7D291A95902C000E1D17 /* wrap_GlyphData.cpp in Sources */, FA0B7DE31A95902C000E1D17 /* wrap_RandomGenerator.cpp in Sources */, @@ -4680,12 +4672,12 @@ FADF54071E3D78F700012CC0 /* Video.cpp in Sources */, 217DFC031D9F6D490055D849 /* timeout.c in Sources */, FA9D8DD71DEF8411002CD881 /* Data.cpp in Sources */, + FABDA9982552448300B5C523 /* b2_contact_manager.cpp in Sources */, FADF542A1E3DAADA00012CC0 /* wrap_Mesh.cpp in Sources */, FA0B7D2B1A95902C000E1D17 /* wrap_Rasterizer.cpp in Sources */, FA0B7E8E1A95902C000E1D17 /* GmeDecoder.cpp in Sources */, FA0B7CD61A95902C000E1D17 /* Audio.cpp in Sources */, FA3C5E421F8C368C0003C579 /* ShaderStage.cpp in Sources */, - FA0B7A9E1A958EA3000E1D17 /* b2PrismaticJoint.cpp in Sources */, FA0B7EAF1A95902C000E1D17 /* System.cpp in Sources */, FA0B7EE21A95902D000E1D17 /* Window.cpp in Sources */, FAF6C9E123C2DE2900D7B5BC /* InReadableOrder.cpp in Sources */, @@ -4697,9 +4689,10 @@ FA0B7ED81A95902D000E1D17 /* wrap_Timer.cpp in Sources */, FAF1407C1E20934C00F898D2 /* linkValidate.cpp in Sources */, FAF6C9DC23C2DE2900D7B5BC /* SpvPostProcess.cpp in Sources */, + FABDA9B32552448300B5C523 /* b2_prismatic_joint.cpp in Sources */, FA0B7DD01A95902C000E1D17 /* love.cpp in Sources */, - FA0B7A521A958EA3000E1D17 /* b2Math.cpp in Sources */, FA0B7D211A95902C000E1D17 /* Rasterizer.cpp in Sources */, + FABDA9F32552448300B5C523 /* b2_chain_shape.cpp in Sources */, FAC7CD7C1FE35E95006A60C7 /* physfs_archiver_slb.c in Sources */, FAF6C9FA23C2DE2900D7B5BC /* disassemble.cpp in Sources */, FAC7CD931FE35E95006A60C7 /* physfs_archiver_zip.c in Sources */, @@ -4707,11 +4700,11 @@ FAF140BB1E20934C00F898D2 /* ossource.cpp in Sources */, FA0B7ECB1A95902C000E1D17 /* wrap_Channel.cpp in Sources */, FACA02F21F5E396B0084B28F /* HashFunction.cpp in Sources */, + FABDA9A02552448300B5C523 /* b2_gear_joint.cpp in Sources */, FAF140A71E20934C00F898D2 /* ShaderLang.cpp in Sources */, FAC271E623B5B5B400C200D3 /* renderstate.cpp in Sources */, FA1BA09D1E16CFCE00AA2803 /* Font.cpp in Sources */, FA0B7E6C1A95902C000E1D17 /* wrap_RevoluteJoint.cpp in Sources */, - FA0B7A5E1A958EA3000E1D17 /* b2Body.cpp in Sources */, FA0B7E631A95902C000E1D17 /* wrap_PolygonShape.cpp in Sources */, FAC7CD7B1FE35E95006A60C7 /* physfs_platform_unix.c in Sources */, FACA02F01F5E396B0084B28F /* DataModule.cpp in Sources */, @@ -4721,25 +4714,30 @@ FAC7CD911FE35E95006A60C7 /* physfs_archiver_grp.c in Sources */, FA27B39D1B498151008A9DCE /* Video.cpp in Sources */, FA15DFAC1F9B8C850042AB22 /* StringMap.cpp in Sources */, + FABDA9AF2552448300B5C523 /* b2_mouse_joint.cpp in Sources */, FA4F2BAC1DE1E37000CA37D7 /* RecordingDevice.cpp in Sources */, - FA0B7A2E1A958EA3000E1D17 /* b2CollideEdge.cpp in Sources */, FA0B7E691A95902C000E1D17 /* wrap_PulleyJoint.cpp in Sources */, + FABDA99E2552448300B5C523 /* b2_edge_circle_contact.cpp in Sources */, FA0B7DB71A95902C000E1D17 /* Joystick.cpp in Sources */, - FA0B7A321A958EA3000E1D17 /* b2Collision.cpp in Sources */, FA91DA8B1F377C3900C80E33 /* deprecation.cpp in Sources */, FA0B7E3F1A95902C000E1D17 /* wrap_ChainShape.cpp in Sources */, + FABDA98F2552448300B5C523 /* b2_world_callbacks.cpp in Sources */, + FABDA9A42552448300B5C523 /* b2_wheel_joint.cpp in Sources */, FA0B7DEB1A95902C000E1D17 /* Cursor.cpp in Sources */, FA0B7D861A95902C000E1D17 /* ImageData.cpp in Sources */, - FA0B7A3E1A958EA3000E1D17 /* b2ChainShape.cpp in Sources */, FAF140731E20934C00F898D2 /* intermOut.cpp in Sources */, FA0B7E0F1A95902C000E1D17 /* FrictionJoint.cpp in Sources */, FA620A351AA2F8DB005DB4C2 /* wrap_Texture.cpp in Sources */, + FABDA9AD2552448300B5C523 /* b2_island.cpp in Sources */, FAF140771E20934C00F898D2 /* iomapper.cpp in Sources */, FA0B7D091A95902C000E1D17 /* wrap_FileData.cpp in Sources */, FA0B7B341A958EA3000E1D17 /* wuff_convert.c in Sources */, FAF140821E20934C00F898D2 /* ParseContextBase.cpp in Sources */, FAF6C9E623C2DE2900D7B5BC /* SpvBuilder.cpp in Sources */, + FABDA9C12552448300B5C523 /* b2_rope.cpp in Sources */, FA0B7D1E1A95902C000E1D17 /* ImageRasterizer.cpp in Sources */, + FABDA9FB2552448300B5C523 /* b2_collide_polygon.cpp in Sources */, + FABDA9D02552448300B5C523 /* b2_draw.cpp in Sources */, FAF140A31E20934C00F898D2 /* Scan.cpp in Sources */, FA0B7EA31A95902C000E1D17 /* SoundData.cpp in Sources */, FA0B79291A958E3B000E1D17 /* Matrix.cpp in Sources */, @@ -4748,15 +4746,14 @@ FA0B7ABF1A958EA3000E1D17 /* host.c in Sources */, FA0B7D4B1A95902C000E1D17 /* Shader.cpp in Sources */, FADF540D1E3D7CDD00012CC0 /* wrap_Video.cpp in Sources */, - FA0B7A581A958EA3000E1D17 /* b2StackAllocator.cpp in Sources */, - FA0B7A301A958EA3000E1D17 /* b2CollidePolygon.cpp in Sources */, - FA0B7A641A958EA3000E1D17 /* b2Fixture.cpp in Sources */, + FABDA9882552448300B5C523 /* b2_contact.cpp in Sources */, FAF140971E20934C00F898D2 /* PpTokens.cpp in Sources */, FAF140A91E20934C00F898D2 /* SymbolTable.cpp in Sources */, FA0B7E181A95902C000E1D17 /* MotorJoint.cpp in Sources */, FA0B7E4E1A95902C000E1D17 /* wrap_Fixture.cpp in Sources */, FA18CEC523D3AE6700263725 /* wrap_Buffer.cpp in Sources */, FAF6C9F423C2DE2900D7B5BC /* Logger.cpp in Sources */, + FABDA9FF2552448300B5C523 /* b2_time_of_impact.cpp in Sources */, FA0B7EBE1A95902C000E1D17 /* Thread.cpp in Sources */, FAC7CD8F1FE35E95006A60C7 /* physfs_platform_posix.c in Sources */, FAF1406E1E20934C00F898D2 /* Initialize.cpp in Sources */, @@ -4765,20 +4762,21 @@ 217DFC091D9F6D490055D849 /* unix.c in Sources */, FACA02EE1F5E396B0084B28F /* Compressor.cpp in Sources */, FAF140801E20934C00F898D2 /* parseConst.cpp in Sources */, - FA0B7AB11A958EA3000E1D17 /* b2Rope.cpp in Sources */, FA4B66C91ABBCF1900558F15 /* Timer.cpp in Sources */, - FA0B7A351A958EA3000E1D17 /* b2Distance.cpp in Sources */, FA0B7E911A95902C000E1D17 /* ModPlugDecoder.cpp in Sources */, FA0B7E511A95902C000E1D17 /* wrap_FrictionJoint.cpp in Sources */, + FABDA9832552448200B5C523 /* b2_chain_polygon_contact.cpp in Sources */, FA0B7AD61A958EA3000E1D17 /* win32.c in Sources */, FADF54341E3DAE6E00012CC0 /* wrap_SpriteBatch.cpp in Sources */, FA0B7E0C1A95902C000E1D17 /* Fixture.cpp in Sources */, FA0B7D181A95902C000E1D17 /* TrueTypeRasterizer.cpp in Sources */, FA0B7CFA1A95902C000E1D17 /* Filesystem.cpp in Sources */, + FABDA9F72552448300B5C523 /* b2_dynamic_tree.cpp in Sources */, + FABDA98A2552448300B5C523 /* b2_revolute_joint.cpp in Sources */, FA1BA0A21E16D97500AA2803 /* wrap_Font.cpp in Sources */, FAC7CD781FE35E95006A60C7 /* physfs_platform_qnx.c in Sources */, FA0B7D3C1A95902C000E1D17 /* Texture.cpp in Sources */, - FA0B7A8C1A958EA3000E1D17 /* b2DistanceJoint.cpp in Sources */, + FABDA9EB2552448300B5C523 /* b2_collide_circle.cpp in Sources */, FADF53FD1E3D74F200012CC0 /* Text.cpp in Sources */, FA6A2B741F60B6710074C308 /* ByteData.cpp in Sources */, 217DFBE91D9F6D490055D849 /* io.c in Sources */, @@ -4789,7 +4787,6 @@ FA9D53AC1F5307E900125C6B /* Deprecations.cpp in Sources */, FA0B7CCD1A95902C000E1D17 /* Audio.cpp in Sources */, FA0B7DCA1A95902C000E1D17 /* Keyboard.cpp in Sources */, - FA0B7AA41A958EA3000E1D17 /* b2RevoluteJoint.cpp in Sources */, FA9D8DDD1DEF842A002CD881 /* Drawable.cpp in Sources */, FA0B7DFA1A95902C000E1D17 /* Body.cpp in Sources */, FAF6C9EB23C2DE2900D7B5BC /* GlslangToSpv.cpp in Sources */, @@ -4800,6 +4797,7 @@ 217DFBFB1D9F6D490055D849 /* serial.c in Sources */, FADF54251E3DA5BA00012CC0 /* Mesh.cpp in Sources */, FA4F2BE51DE6650600CA37D7 /* wrap_Transform.cpp in Sources */, + FABDA9A22552448300B5C523 /* b2_friction_joint.cpp in Sources */, 217DFC0D1D9F6D490055D849 /* unixudp.c in Sources */, FA0B7CDC1A95902C000E1D17 /* Source.cpp in Sources */, FA0B7DC41A95902C000E1D17 /* wrap_JoystickModule.cpp in Sources */, @@ -4808,20 +4806,17 @@ FA0B7AB51A958EA3000E1D17 /* ddsparse.cpp in Sources */, FACA02F41F5E396B0084B28F /* wrap_CompressedData.cpp in Sources */, FAF140AC1E20934C00F898D2 /* Versions.cpp in Sources */, - FA0B7A441A958EA3000E1D17 /* b2EdgeShape.cpp in Sources */, FA0B79461A958E3B000E1D17 /* Vector.cpp in Sources */, FAC7CD811FE35E95006A60C7 /* physfs_platform_os2.c in Sources */, + FABDA9962552448300B5C523 /* b2_distance_joint.cpp in Sources */, FA0B7DBB1A95902C000E1D17 /* Joystick.cpp in Sources */, FAF140DB1E20934C00F898D2 /* InitializeDll.cpp in Sources */, FA0B7DAE1A95902C000E1D17 /* wrap_CompressedImageData.cpp in Sources */, FA6A2B701F5F845F0074C308 /* wrap_DataView.cpp in Sources */, - FA0B7A6E1A958EA3000E1D17 /* b2WorldCallbacks.cpp in Sources */, - FA0B7A831A958EA3000E1D17 /* b2EdgeAndPolygonContact.cpp in Sources */, - FA0B7AA11A958EA3000E1D17 /* b2PulleyJoint.cpp in Sources */, FAB17BE61ABFAA9000F9BA27 /* lz4.c in Sources */, FA0B7B211A958EA3000E1D17 /* luasocket.cpp in Sources */, - FA0B7A5B1A958EA3000E1D17 /* b2Timer.cpp in Sources */, FA0B7CD91A95902C000E1D17 /* Pool.cpp in Sources */, + FABDA98D2552448300B5C523 /* b2_contact_solver.cpp in Sources */, FAF140A01E20934C00F898D2 /* RemoveTree.cpp in Sources */, FA0B7E151A95902C000E1D17 /* Joint.cpp in Sources */, FA0B7EE81A95902D000E1D17 /* wrap_Window.cpp in Sources */, @@ -4835,7 +4830,6 @@ FAAA3FDB1F64B3AD00F89E99 /* lutf8lib.c in Sources */, FAF1408A1E20934C00F898D2 /* Pp.cpp in Sources */, FA76344A1E28722A0066EF9E /* StreamBuffer.cpp in Sources */, - FA0B7A7A1A958EA3000E1D17 /* b2Contact.cpp in Sources */, FA0B7DF11A95902C000E1D17 /* wrap_Cursor.cpp in Sources */, FA0B7E001A95902C000E1D17 /* CircleShape.cpp in Sources */, FA0B7E451A95902C000E1D17 /* wrap_Contact.cpp in Sources */, @@ -4848,15 +4842,16 @@ FADF53F81E3C7ACD00012CC0 /* Buffer.cpp in Sources */, FA0B7DD91A95902C000E1D17 /* RandomGenerator.cpp in Sources */, FAF1409A1E20934C00F898D2 /* propagateNoContraction.cpp in Sources */, - FA0B7A9B1A958EA3000E1D17 /* b2MouseJoint.cpp in Sources */, FA2AF6741DAD64970032B62C /* vertex.cpp in Sources */, + FABDA9932552448300B5C523 /* b2_polygon_circle_contact.cpp in Sources */, FAC7CD851FE35E95006A60C7 /* physfs_unicode.c in Sources */, FA6A2B7A1F60B8250074C308 /* wrap_ByteData.cpp in Sources */, FAF140551E20934C00F898D2 /* Link.cpp in Sources */, + FABDA9792552448200B5C523 /* b2_joint.cpp in Sources */, FAF140841E20934C00F898D2 /* ParseHelper.cpp in Sources */, FA0B7D7F1A95902C000E1D17 /* Volatile.cpp in Sources */, - FA0B7A3B1A958EA3000E1D17 /* b2TimeOfImpact.cpp in Sources */, FA1BA0B11E16FD0800AA2803 /* Shader.cpp in Sources */, + FABDA99A2552448300B5C523 /* b2_polygon_contact.cpp in Sources */, 217DFBED1D9F6D490055D849 /* luasocket.c in Sources */, 217DFC011D9F6D490055D849 /* tcp.c in Sources */, FA0B7EBB1A95902C000E1D17 /* LuaThread.cpp in Sources */, @@ -4864,37 +4859,37 @@ FAC7CD881FE35E95006A60C7 /* physfs_platform_apple.m in Sources */, FA0B7D391A95902C000E1D17 /* Graphics.cpp in Sources */, FA0B7E121A95902C000E1D17 /* GearJoint.cpp in Sources */, + FABDA9F52552448300B5C523 /* b2_broad_phase.cpp in Sources */, FAE272521C05A15B00A67640 /* ParticleSystem.cpp in Sources */, FA0B7DC11A95902C000E1D17 /* wrap_Joystick.cpp in Sources */, + FABDA99C2552448300B5C523 /* b2_edge_polygon_contact.cpp in Sources */, FA0B7CD31A95902C000E1D17 /* Source.cpp in Sources */, - FA0B7A411A958EA3000E1D17 /* b2CircleShape.cpp in Sources */, FA0B7CD01A95902C000E1D17 /* Audio.cpp in Sources */, FAA3A9AE1B7D465A00CED060 /* android.cpp in Sources */, FA0B7D121A95902C000E1D17 /* Font.cpp in Sources */, + FABDA9AB2552448300B5C523 /* b2_world.cpp in Sources */, FA0B7EC81A95902C000E1D17 /* threads.cpp in Sources */, FAC7CD8B1FE35E95006A60C7 /* physfs_archiver_iso9660.c in Sources */, 217DFBF91D9F6D490055D849 /* select.c in Sources */, - FA0B7A6B1A958EA3000E1D17 /* b2World.cpp in Sources */, + FABDA9D42552448300B5C523 /* b2_block_allocator.cpp in Sources */, FAF1408C1E20934C00F898D2 /* PpAtom.cpp in Sources */, - FA0B7A801A958EA3000E1D17 /* b2EdgeAndCircleContact.cpp in Sources */, + FABDA9EF2552448300B5C523 /* b2_collision.cpp in Sources */, FAF140711E20934C00F898D2 /* Intermediate.cpp in Sources */, FAF6C9F823C2DE2900D7B5BC /* doc.cpp in Sources */, FAC7CD7D1FE35E95006A60C7 /* physfs_platform_winrt.cpp in Sources */, FA0B7E541A95902C000E1D17 /* wrap_GearJoint.cpp in Sources */, FA0A3A6023366CE9001C269E /* floattypes.cpp in Sources */, FA41A3C81C0A1F950084430C /* ASTCHandler.cpp in Sources */, + FABDA9DA2552448300B5C523 /* b2_math.cpp in Sources */, FA0B7E781A95902C000E1D17 /* wrap_WheelJoint.cpp in Sources */, FA0B7DDC1A95902C000E1D17 /* wrap_BezierCurve.cpp in Sources */, - FA0B7A951A958EA3000E1D17 /* b2Joint.cpp in Sources */, FA0B7D061A95902C000E1D17 /* wrap_File.cpp in Sources */, FAC7CD871FE35E95006A60C7 /* physfs_archiver_vdf.c in Sources */, - FA0B7A4E1A958EA3000E1D17 /* b2Draw.cpp in Sources */, FAD19A171DFF8CA200D5398A /* ImageDataBase.cpp in Sources */, FA27B3C01B4985BF008A9DCE /* wrap_VideoStream.cpp in Sources */, FADF54201E3DA52C00012CC0 /* wrap_ParticleSystem.cpp in Sources */, FA0B7D9F1A95902C000E1D17 /* KTXHandler.cpp in Sources */, FA1E88831DF363DB00E808AA /* Filter.cpp in Sources */, - FA0B7A2C1A958EA3000E1D17 /* b2CollideCircle.cpp in Sources */, FA0B7CEB1A95902C000E1D17 /* Event.cpp in Sources */, FA1557C31CE90BD200AFF582 /* EXRHandler.cpp in Sources */, FA27B3AA1B498151008A9DCE /* VideoStream.cpp in Sources */, @@ -4902,12 +4897,12 @@ FA0B7E301A95902C000E1D17 /* Shape.cpp in Sources */, FA93C4541F315B960087CCD4 /* FormatHandler.cpp in Sources */, FA0B7E481A95902C000E1D17 /* wrap_DistanceJoint.cpp in Sources */, - FA0B7A8F1A958EA3000E1D17 /* b2FrictionJoint.cpp in Sources */, + FABDA9A72552448300B5C523 /* b2_motor_joint.cpp in Sources */, FA0B792F1A958E3B000E1D17 /* Module.cpp in Sources */, FA0B7E2A1A95902C000E1D17 /* RevoluteJoint.cpp in Sources */, - FA0B7A711A958EA3000E1D17 /* b2ChainAndCircleContact.cpp in Sources */, FA0B7D251A95902C000E1D17 /* wrap_Font.cpp in Sources */, FA0B7E091A95902C000E1D17 /* EdgeShape.cpp in Sources */, + FABDA9912552448300B5C523 /* b2_pulley_joint.cpp in Sources */, FA0B7CF71A95902C000E1D17 /* FileData.cpp in Sources */, FAC7CD8C1FE35E95006A60C7 /* physfs_archiver_qpak.c in Sources */, FA0B7DA51A95902C000E1D17 /* PNGHandler.cpp in Sources */, @@ -4915,16 +4910,13 @@ FA0B7E971A95902C000E1D17 /* Sound.cpp in Sources */, FA4F2B791DE0125B00CA37D7 /* xxhash.c in Sources */, FA0B7E361A95902C000E1D17 /* WheelJoint.cpp in Sources */, - FA0B7A471A958EA3000E1D17 /* b2PolygonShape.cpp in Sources */, FADF542F1E3DABF600012CC0 /* SpriteBatch.cpp in Sources */, FA0B7D8D1A95902C000E1D17 /* ddsHandler.cpp in Sources */, + FABDA9A92552448300B5C523 /* b2_rope_joint.cpp in Sources */, FAAA3FD91F64B3AD00F89E99 /* lstrlib.c in Sources */, FA0B7DFD1A95902C000E1D17 /* ChainShape.cpp in Sources */, FA0B79201A958E3B000E1D17 /* delay.cpp in Sources */, - FA0B7A4B1A958EA3000E1D17 /* b2BlockAllocator.cpp in Sources */, - FA0B7A551A958EA3000E1D17 /* b2Settings.cpp in Sources */, FA0B7EA91A95902C000E1D17 /* wrap_Sound.cpp in Sources */, - FA0B7A981A958EA3000E1D17 /* b2MotorJoint.cpp in Sources */, FA6A2B671F5F7B6B0074C308 /* wrap_Data.cpp in Sources */, FA0B7E061A95902C000E1D17 /* DistanceJoint.cpp in Sources */, FA620A321AA2F8DB005DB4C2 /* wrap_Quad.cpp in Sources */, @@ -4934,21 +4926,18 @@ FAC7CD7E1FE35E95006A60C7 /* physfs_archiver_mvl.c in Sources */, FA0B793B1A958E3B000E1D17 /* runtime.cpp in Sources */, FA0B7E5D1A95902C000E1D17 /* wrap_MouseJoint.cpp in Sources */, - FA0B7A741A958EA3000E1D17 /* b2ChainAndPolygonContact.cpp in Sources */, FA0B7AD41A958EA3000E1D17 /* unix.c in Sources */, - FA0B7A771A958EA3000E1D17 /* b2CircleContact.cpp in Sources */, FADF543B1E3DAFF700012CC0 /* wrap_Graphics.cpp in Sources */, FA0B7E8B1A95902C000E1D17 /* FLACDecoder.cpp in Sources */, FA0B7B3A1A958EA3000E1D17 /* wuff_memory.c in Sources */, - FA0B7A381A958EA3000E1D17 /* b2DynamicTree.cpp in Sources */, FAECA1B21F3164700095D008 /* CompressedSlice.cpp in Sources */, FA0B7D481A95902C000E1D17 /* Polyline.cpp in Sources */, 217DFC111D9F6D490055D849 /* usocket.c in Sources */, FAC7CD891FE35E95006A60C7 /* physfs_archiver_dir.c in Sources */, FAF140751E20934C00F898D2 /* IntermTraverse.cpp in Sources */, FA0B7CE21A95902C000E1D17 /* wrap_Audio.cpp in Sources */, - FA0B7AAA1A958EA3000E1D17 /* b2WeldJoint.cpp in Sources */, FA0B7DF71A95902C000E1D17 /* Body.cpp in Sources */, + FABDA9ED2552448300B5C523 /* b2_circle_shape.cpp in Sources */, FA0B7DF41A95902C000E1D17 /* wrap_Mouse.cpp in Sources */, FA0B7E851A95902C000E1D17 /* CoreAudioDecoder.cpp in Sources */, FA0B7E751A95902C000E1D17 /* wrap_WeldJoint.cpp in Sources */, @@ -4964,6 +4953,7 @@ FA28EBD51E352DB5003446F4 /* FenceSync.cpp in Sources */, FA0B7E1B1A95902C000E1D17 /* MouseJoint.cpp in Sources */, FA0B7CF41A95902C000E1D17 /* File.cpp in Sources */, + FABDA9B52552448300B5C523 /* b2_fixture.cpp in Sources */, FAC7CD7A1FE35E95006A60C7 /* physfs_archiver_7z.c in Sources */, FA0B7E331A95902C000E1D17 /* WeldJoint.cpp in Sources */, FA0B7D301A95902C000E1D17 /* Graphics.cpp in Sources */, @@ -4976,33 +4966,34 @@ FA522D4D23F9FE380059EE3C /* MP3Decoder.cpp in Sources */, FA9D8DD11DEB56C3002CD881 /* pixelformat.cpp in Sources */, FA0B7E661A95902C000E1D17 /* wrap_PrismaticJoint.cpp in Sources */, + FABDA9B12552448300B5C523 /* b2_circle_contact.cpp in Sources */, + FABDA9812552448200B5C523 /* b2_weld_joint.cpp in Sources */, FA0B7DCD1A95902C000E1D17 /* wrap_Keyboard.cpp in Sources */, FA0B7EE51A95902D000E1D17 /* Window.cpp in Sources */, FA6A2B6A1F5F7F560074C308 /* DataView.cpp in Sources */, + FABDA9D22552448300B5C523 /* b2_timer.cpp in Sources */, FA3C5E471F8D80CA0003C579 /* ShaderStage.cpp in Sources */, FA0B7E391A95902C000E1D17 /* World.cpp in Sources */, FA0B7ABD1A958EA3000E1D17 /* compress.c in Sources */, FA0B7ACB1A958EA3000E1D17 /* list.c in Sources */, FA0B7E7E1A95902C000E1D17 /* Joint.cpp in Sources */, - FA0B7A861A958EA3000E1D17 /* b2PolygonAndCircleContact.cpp in Sources */, FA0B7DB11A95902C000E1D17 /* wrap_Image.cpp in Sources */, + FABDA9D82552448300B5C523 /* b2_settings.cpp in Sources */, FAC7CD831FE35E95006A60C7 /* physfs_platform_windows.c in Sources */, FA0B7E881A95902C000E1D17 /* Decoder.cpp in Sources */, FA0B7E3C1A95902C000E1D17 /* wrap_Body.cpp in Sources */, FA0B7D791A95902C000E1D17 /* Quad.cpp in Sources */, + FABDA9FD2552448300B5C523 /* b2_edge_shape.cpp in Sources */, FAC756F51E4F99B400B91289 /* Effect.cpp in Sources */, FA620A3A1AA305F6005DB4C2 /* types.cpp in Sources */, FA0B7DD31A95902C000E1D17 /* BezierCurve.cpp in Sources */, FA0B7E7B1A95902C000E1D17 /* wrap_World.cpp in Sources */, FA0B7B281A958EA3000E1D17 /* simplexnoise1234.cpp in Sources */, FA0B7D421A95902C000E1D17 /* OpenGL.cpp in Sources */, - FA0B7A671A958EA3000E1D17 /* b2Island.cpp in Sources */, FA0B7DBE1A95902C000E1D17 /* JoystickModule.cpp in Sources */, FAB2D5AA1AABDD8A008224A4 /* TrueTypeRasterizer.cpp in Sources */, FA0B7ACD1A958EA3000E1D17 /* packet.c in Sources */, - FA0B7A921A958EA3000E1D17 /* b2GearJoint.cpp in Sources */, FA0B7E5A1A95902C000E1D17 /* wrap_MotorJoint.cpp in Sources */, - FA0B7AA71A958EA3000E1D17 /* b2RopeJoint.cpp in Sources */, FA0B7DD61A95902C000E1D17 /* MathModule.cpp in Sources */, FAC7CD8A1FE35E95006A60C7 /* physfs_byteorder.c in Sources */, FA0B7D0F1A95902C000E1D17 /* BMFontRasterizer.cpp in Sources */, @@ -5012,7 +5003,6 @@ FA0B7E241A95902C000E1D17 /* PrismaticJoint.cpp in Sources */, FAC7CD791FE35E95006A60C7 /* physfs.c in Sources */, FAC756FA1E4F99D200B91289 /* Effect.cpp in Sources */, - FA0B7A7D1A958EA3000E1D17 /* b2ContactSolver.cpp in Sources */, FA0B7E601A95902C000E1D17 /* wrap_Physics.cpp in Sources */, FA0B7DC71A95902C000E1D17 /* Keyboard.cpp in Sources */, 217DFC071D9F6D490055D849 /* udp.c in Sources */, @@ -5023,34 +5013,36 @@ FA0B79431A958E3B000E1D17 /* Variant.cpp in Sources */, FA4F2BE31DE6650600CA37D7 /* Transform.cpp in Sources */, FA0B7EA01A95902C000E1D17 /* Sound.cpp in Sources */, + FABDA9F12552448300B5C523 /* b2_collide_edge.cpp in Sources */, FA0B7DE51A95902C000E1D17 /* Cursor.cpp in Sources */, FA0B7EDB1A95902D000E1D17 /* Touch.cpp in Sources */, FA0B7CE81A95902C000E1D17 /* Event.cpp in Sources */, FA0B7ACF1A958EA3000E1D17 /* peer.c in Sources */, FA0B7ADE1A958EA3000E1D17 /* lodepng.cpp in Sources */, - FA0B7A291A958EA3000E1D17 /* b2BroadPhase.cpp in Sources */, - FA0B7A891A958EA3000E1D17 /* b2PolygonContact.cpp in Sources */, FA0B7E1E1A95902C000E1D17 /* Physics.cpp in Sources */, FA9D8DE01DEF843D002CD881 /* Image.cpp in Sources */, FA0B7E811A95902C000E1D17 /* Shape.cpp in Sources */, + FABDA97C2552448200B5C523 /* b2_chain_circle_contact.cpp in Sources */, FAC8E54623AC832A007B07C8 /* NativeFile.cpp in Sources */, FA4F2BA81DE1E36400CA37D7 /* wrap_RecordingDevice.cpp in Sources */, FACA02EC1F5E396B0084B28F /* CompressedData.cpp in Sources */, FAF140531E20934C00F898D2 /* CodeGen.cpp in Sources */, FA27B3B31B498151008A9DCE /* wrap_Video.cpp in Sources */, - FA0B7A611A958EA3000E1D17 /* b2ContactManager.cpp in Sources */, 217DFC0B1D9F6D490055D849 /* unixtcp.c in Sources */, FAF140881E20934C00F898D2 /* PoolAlloc.cpp in Sources */, - FA0B7AAD1A958EA3000E1D17 /* b2WheelJoint.cpp in Sources */, FA0B7DEE1A95902C000E1D17 /* Mouse.cpp in Sources */, FAA54ACC1F91660400A8FA7B /* TheoraVideoStream.cpp in Sources */, FA1E887E1DF363CD00E808AA /* Filter.cpp in Sources */, + FABDA9862552448200B5C523 /* b2_body.cpp in Sources */, FA0B7D281A95902C000E1D17 /* wrap_GlyphData.cpp in Sources */, + FABDA9F92552448300B5C523 /* b2_polygon_shape.cpp in Sources */, FA0B7DE21A95902C000E1D17 /* wrap_RandomGenerator.cpp in Sources */, FAF6C9F223C2DE2900D7B5BC /* SPVRemapper.cpp in Sources */, + FABDAA012552448300B5C523 /* b2_distance.cpp in Sources */, FACA02F61F5E396B0084B28F /* wrap_DataModule.cpp in Sources */, FA0B79401A958E3B000E1D17 /* utf8.cpp in Sources */, FA0B79241A958E3B000E1D17 /* Exception.cpp in Sources */, + FABDA9D62552448300B5C523 /* b2_stack_allocator.cpp in Sources */, FA0B7D0C1A95902C000E1D17 /* wrap_Filesystem.cpp in Sources */, FA0B7AD91A958EA3000E1D17 /* glad.cpp in Sources */, FAC7CD841FE35E95006A60C7 /* physfs_archiver_unpacked.c in Sources */, diff --git a/src/libraries/box2d/dynamics/b2_island.cpp b/src/libraries/box2d/dynamics/b2_island.cpp index 48d89a850..bd42b5446 100644 --- a/src/libraries/box2d/dynamics/b2_island.cpp +++ b/src/libraries/box2d/dynamics/b2_island.cpp @@ -30,7 +30,7 @@ #include "box2d/b2_world.h" #include "b2_island.h" -#include "dynamics/b2_contact_solver.h" +#include "b2_contact_solver.h" /* Position Correction Notes From 7a18190c5c8b83930f77bedc02d7168b20dfddd6 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Tue, 3 Nov 2020 22:12:56 -0400 Subject: [PATCH 41/57] Restructure SpriteBatch internal vertex data --- src/modules/graphics/SpriteBatch.cpp | 84 +++++++++++++++++----------- src/modules/graphics/SpriteBatch.h | 8 ++- 2 files changed, 57 insertions(+), 35 deletions(-) diff --git a/src/modules/graphics/SpriteBatch.cpp b/src/modules/graphics/SpriteBatch.cpp index 677f69352..285564f3e 100644 --- a/src/modules/graphics/SpriteBatch.cpp +++ b/src/modules/graphics/SpriteBatch.cpp @@ -47,6 +47,9 @@ SpriteBatch::SpriteBatch(Graphics *gfx, Texture *texture, int size, BufferUsage , color(255, 255, 255, 255) , colorf(1.0f, 1.0f, 1.0f, 1.0f) , array_buf(nullptr) + , vertex_data(nullptr) + , modified_sprite_first(LOVE_INT32_MAX) + , modified_sprite_last(0) , range_start(-1) , range_count(-1) { @@ -64,14 +67,22 @@ SpriteBatch::SpriteBatch(Graphics *gfx, Texture *texture, int size, BufferUsage vertex_stride = getFormatStride(vertex_format); size_t vertex_size = vertex_stride * 4 * size; + + vertex_data = (uint8 *) malloc(vertex_size); + if (vertex_data == nullptr) + throw love::Exception("Out of memory."); + + memset(vertex_data, 0, vertex_size); + Buffer::Settings settings(Buffer::TYPEFLAG_VERTEX, Buffer::MAP_EXPLICIT_RANGE_MODIFY, usage); auto decl = Buffer::getCommonFormatDeclaration(vertex_format); - array_buf = gfx->newBuffer(settings, decl, nullptr, vertex_size, 0); + + array_buf.set(gfx->newBuffer(settings, decl, nullptr, vertex_size, 0), Acquire::NORETAIN); } SpriteBatch::~SpriteBatch() { - delete array_buf; + free(vertex_data); } int SpriteBatch::add(const Matrix4 &m, int index /*= -1*/) @@ -93,9 +104,10 @@ int SpriteBatch::add(Quad *quad, const Matrix4 &m, int index /*= -1*/) const Vector2 *quadpositions = quad->getVertexPositions(); const Vector2 *quadtexcoords = quad->getVertexTexCoords(); - // Always keep the buffer mapped when adding data (it'll be unmapped on draw.) - size_t offset = (index == -1 ? next : index) * vertex_stride * 4; - auto verts = (XYf_STf_RGBAub *) ((uint8 *) array_buf->map() + offset); + int spriteindex = (index == -1 ? next : index); + + size_t offset = spriteindex * vertex_stride * 4; + auto verts = (XYf_STf_RGBAub *) (vertex_data + offset); m.transformXY(verts, quadpositions, 4); @@ -106,7 +118,8 @@ int SpriteBatch::add(Quad *quad, const Matrix4 &m, int index /*= -1*/) verts[i].color = color; } - array_buf->setMappedRangeModified(offset, vertex_stride * 4); + modified_sprite_first = std::min(modified_sprite_first, spriteindex); + modified_sprite_last = std::max(modified_sprite_last, spriteindex); // Increment counter. if (index == -1) @@ -137,9 +150,10 @@ int SpriteBatch::addLayer(int layer, Quad *quad, const Matrix4 &m, int index) const Vector2 *quadpositions = quad->getVertexPositions(); const Vector2 *quadtexcoords = quad->getVertexTexCoords(); - // Always keep the buffer mapped when adding data (it'll be unmapped on draw.) - size_t offset = (index == -1 ? next : index) * vertex_stride * 4; - auto verts = (XYf_STPf_RGBAub *) ((uint8 *) array_buf->map() + offset); + int spriteindex = (index == -1 ? next : index); + + size_t offset = spriteindex * vertex_stride * 4; + auto verts = (XYf_STPf_RGBAub *) (vertex_data + offset); m.transformXY(verts, quadpositions, 4); @@ -151,7 +165,8 @@ int SpriteBatch::addLayer(int layer, Quad *quad, const Matrix4 &m, int index) verts[i].color = color; } - array_buf->setMappedRangeModified(offset, vertex_stride * 4); + modified_sprite_first = std::min(modified_sprite_first, spriteindex); + modified_sprite_last = std::max(modified_sprite_last, spriteindex); // Increment counter. if (index == -1) @@ -168,7 +183,20 @@ void SpriteBatch::clear() void SpriteBatch::flush() { - array_buf->unmap(); + if (modified_sprite_first <= modified_sprite_last) + { + size_t offset = modified_sprite_first * vertex_stride * 4; + size_t size = (modified_sprite_last - modified_sprite_first) * vertex_stride * 4; + + // TODO: switch this to fill() once it gets cleaned up. + memcpy(((uint8 *)array_buf->map() + offset), vertex_data + offset, size); + + array_buf->setMappedRangeModified(offset, size); + array_buf->unmap(); + + modified_sprite_first = LOVE_INT32_MAX; + modified_sprite_last = 0; + } } void SpriteBatch::setTexture(Texture *newtexture) @@ -213,33 +241,24 @@ void SpriteBatch::setBufferSize(int newsize) return; size_t vertex_size = vertex_stride * 4 * newsize; - love::graphics::Buffer *new_array_buf = nullptr; int new_next = std::min(next, newsize); - try - { - auto gfx = Module::getInstance(Module::M_GRAPHICS); - Buffer::Settings settings(array_buf->getTypeFlags(), array_buf->getMapFlags(), array_buf->getUsage()); - auto decl = Buffer::getCommonFormatDeclaration(vertex_format); - new_array_buf = gfx->newBuffer(settings, decl, nullptr, vertex_size, 0); + void *new_vertex_data = realloc(vertex_data, vertex_size); + if (new_vertex_data == nullptr) + throw love::Exception("Out of memory."); - // Copy as much of the old data into the new GLBuffer as can fit. - size_t copy_size = vertex_stride * 4 * new_next; - array_buf->copyTo(0, copy_size, new_array_buf, 0); - } - catch (love::Exception &) - { - delete new_array_buf; - throw; - } + auto gfx = Module::getInstance(Module::M_GRAPHICS); + Buffer::Settings settings(array_buf->getTypeFlags(), array_buf->getMapFlags(), array_buf->getUsage()); + auto decl = Buffer::getCommonFormatDeclaration(vertex_format); - // We don't need to unmap the old GLBuffer since we're deleting it. - delete array_buf; + array_buf.set(gfx->newBuffer(settings, decl, nullptr, vertex_size, 0), Acquire::NORETAIN); + + array_buf->fill(0, vertex_stride * 4 * new_next, new_vertex_data); + + vertex_data = (uint8 *) new_vertex_data; - array_buf = new_array_buf; size = newsize; - next = new_next; } @@ -319,8 +338,7 @@ void SpriteBatch::draw(Graphics *gfx, const Matrix4 &m) Shader::current->checkMainTexture(texture); } - // Make sure the buffer isn't mapped when we draw (sends data to GPU if needed.) - array_buf->unmap(); + flush(); // Upload any modified sprite data to the GPU. VertexAttributes attributes; BufferBindings buffers; diff --git a/src/modules/graphics/SpriteBatch.h b/src/modules/graphics/SpriteBatch.h index 40fbfd932..0266f257f 100644 --- a/src/modules/graphics/SpriteBatch.h +++ b/src/modules/graphics/SpriteBatch.h @@ -130,8 +130,12 @@ private: CommonFormat vertex_format; size_t vertex_stride; - - love::graphics::Buffer *array_buf; + + StrongRef array_buf; + uint8 *vertex_data; + + int modified_sprite_first; + int modified_sprite_last; std::unordered_map attached_attributes; From e32935e0f6684440ba18653988ea388ccbfb8b0b Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Wed, 11 Nov 2020 15:11:00 -0400 Subject: [PATCH 42/57] Backport Canvas memory stats fix from 12.0. Fixes #1642 --- src/modules/graphics/opengl/Canvas.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/modules/graphics/opengl/Canvas.cpp b/src/modules/graphics/opengl/Canvas.cpp index c6a2ba7c5..9bd14ab51 100644 --- a/src/modules/graphics/opengl/Canvas.cpp +++ b/src/modules/graphics/opengl/Canvas.cpp @@ -287,12 +287,18 @@ bool Canvas::loadVolatile() if (!isReadable() || actualSamples > 0) createRenderbuffer(pixelWidth, pixelHeight, actualSamples, format, renderbuffer); - int64 memsize = getPixelFormatSize(format) * pixelWidth * pixelHeight; - if (getMipmapCount() > 1) - memsize *= 1.33334; + int64 memsize = 0; + + for (int mip = 0; mip < getMipmapCount(); mip++) + { + int w = getPixelWidth(mip); + int h = getPixelHeight(mip); + int slices = getDepth(mip) * layers * (texType == TEXTURE_CUBE ? 6 : 1); + memsize += getPixelFormatSize(format) * w * h * slices; + } if (actualSamples > 1 && isReadable()) - memsize += getPixelFormatSize(format) * pixelWidth * pixelHeight * actualSamples; + memsize += memsize * actualSamples; else if (actualSamples > 1) memsize *= actualSamples; From 1bcae1abe995c7d8c7a175a6b764dfa873ea8876 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Wed, 11 Nov 2020 16:07:35 -0400 Subject: [PATCH 43/57] Update changelog --- changes.txt | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/changes.txt b/changes.txt index 5ae76fc4d..2ef98cd47 100644 --- a/changes.txt +++ b/changes.txt @@ -1,3 +1,28 @@ +LOVE 11.4 [Mysterious Mysteries] +-------------------------------- + +Released: N/A + +* Added support for r16, rg16, and rgba16 pixel formats in Canvases. +* Added Shader:send(name, matrixlayout, data, ...) variant, whose argument order is more consistent than Shader:send(name, data, matrixlayout, ...). + +* Changed love.timer.getTime to start at 0 when the module is first loaded. + +* Fixed build-time compatibility with Lua 5.4. +* Fixed initial window creation to set the window's title during creation instead of after. +* Fixed drag-and-drop to open a love game on macOS causing love.event.quit("restart") to fail. +* Fixed fused macOS apps opening other love games when drag-and-drop is used (if the fused app hasn't already removed .love files from recognized document types). +* Fixed memory corruption and a crash when drawing smooth lines. +* Fixed a crash in Canvas:newImageData when the pixel format's pixel byte size multiplied by its width isn't a multiple of 4. +* Fixed love.graphics.newVolumeImage when explicit mipmaps are provided. +* Fixed freezes and crashes in automatic batching when an AMD GPU is used. +* Fixed love.graphics.print and Image:replacePixels on more AMD/ATI GPUs. +* Fixed texture memory reported by love.graphics.getStats when a volume or array Canvas is created. +* Fixed rare issues where textures were not sent to shaders correctly. +* Fixed Shader:send(name, data, matrixlayout, ...). +* Fixed source code compilation on Xcode 12+. +* Fixed source code compilation on Linux systems that don't provide posix_spawn APIs. + LOVE 11.3 [Mysterious Mysteries] -------------------------------- From 5608db4bb05766e5547079de88e8427ad8272354 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Wed, 11 Nov 2020 16:35:27 -0400 Subject: [PATCH 44/57] Updated changelog --- changes.txt | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/changes.txt b/changes.txt index 2ef98cd47..09dfa0633 100644 --- a/changes.txt +++ b/changes.txt @@ -1,3 +1,37 @@ +LOVE 12.0 [N/A] + +Released: N/A + +* Added love.event.restart(optionalvalue). A new love.restart field will contain the value after restarting. +* Added SoundData:copyFrom. +* Added SoundData:slice. +* Added t.highdpi startup flag in love.conf, replacing t.window.highdpi and the highdpi flag of love.window.setMode. +* Added per-shader opt in support for the GLSL 4.30 (desktop) and GLSL ES 3.10 (mobile) shading languages, via #pragma language glsl4. +* Added love.graphics.newTexture. newImage and newCanvas still exist as convenience constructor functions. +* Added love.graphics.getTextureFormats, which replaces getImageFormats and getCanvasFormats. +* Added Graphics Buffer objects, including vertex, index, and texel buffers. +* Added APIs for interacting with the objects owned by Meshes. +* Added Mesh:getAttachedAttributes. +* Added integer buffer data formats. +* Added love.graphics.setBlendState, which gives lower level control over blend operations than setBlendMode. +* Added new 'clampone' wrap mode. + +* Changed the default font from Vera size 12 to Noto Sans size 13. +* Changed the Texture class and implementation to no longer have separate Canvas and Image subclasses. +* Changed Images to no longer hold onto a CPU copy of their pixel data after creation. +* Changed love.window.setMode to no longer clear the contents of Canvases or otherwise recreate OpenGL resources. + +* Updated Box2D from 2.3 to 2.4.1. + +* Deprecated love.graphics.getImageFormats and love.graphics.getCanvasFormats (replaced by getTextureFormats). +* Deprecated t.window.highdpi in love.conf and the highdpi flag of love.window.setMode (replaced by t.highdpi in love.conf). +* Deprecated the variants of Mesh:attachAttribute and SpriteBatch:attachAttribute which accept a Mesh (replaced by variants which accept a Buffer). + +* Removed the variant of SpriteBatch:setColor() which turns off all previously set colors. + +* Fixed BezierCurve:render adding collinear points in some situations. + + LOVE 11.4 [Mysterious Mysteries] -------------------------------- From 6a1f4ecabe504a44a997944475e510a55645caa1 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Wed, 11 Nov 2020 21:04:24 -0400 Subject: [PATCH 45/57] Changelog formatting fix --- changes.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/changes.txt b/changes.txt index 09dfa0633..625fe0b63 100644 --- a/changes.txt +++ b/changes.txt @@ -1,4 +1,5 @@ LOVE 12.0 [N/A] +--------------- Released: N/A @@ -10,7 +11,7 @@ Released: N/A * Added love.graphics.newTexture. newImage and newCanvas still exist as convenience constructor functions. * Added love.graphics.getTextureFormats, which replaces getImageFormats and getCanvasFormats. * Added Graphics Buffer objects, including vertex, index, and texel buffers. -* Added APIs for interacting with the objects owned by Meshes. +* Added APIs for interacting with the Buffer objects owned by Meshes. * Added Mesh:getAttachedAttributes. * Added integer buffer data formats. * Added love.graphics.setBlendState, which gives lower level control over blend operations than setBlendMode. @@ -31,7 +32,6 @@ Released: N/A * Fixed BezierCurve:render adding collinear points in some situations. - LOVE 11.4 [Mysterious Mysteries] -------------------------------- From fc2cf602f67cbf97286f6b307baff104228e3629 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Thu, 12 Nov 2020 23:46:49 -0400 Subject: [PATCH 46/57] Fix RopeJoints not working. --- CMakeLists.txt | 1 - .../xcode/liblove.xcodeproj/project.pbxproj | 10 - src/libraries/box2d/Box2D.h | 1 - src/libraries/box2d/b2_rope_joint.h | 118 --------- .../box2d/dynamics/b2_rope_joint.cpp | 234 ------------------ src/modules/physics/box2d/RopeJoint.cpp | 4 +- src/modules/physics/box2d/RopeJoint.h | 2 +- 7 files changed, 3 insertions(+), 367 deletions(-) delete mode 100644 src/libraries/box2d/b2_rope_joint.h delete mode 100644 src/libraries/box2d/dynamics/b2_rope_joint.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 47daad5e3..c9d29ddc8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1123,7 +1123,6 @@ set(LOVE_SRC_3P_BOX2D_DYNAMICS src/libraries/box2d/dynamics/b2_prismatic_joint.cpp src/libraries/box2d/dynamics/b2_pulley_joint.cpp src/libraries/box2d/dynamics/b2_revolute_joint.cpp - src/libraries/box2d/dynamics/b2_rope_joint.cpp src/libraries/box2d/dynamics/b2_weld_joint.cpp src/libraries/box2d/dynamics/b2_wheel_joint.cpp src/libraries/box2d/dynamics/b2_world.cpp diff --git a/platform/xcode/liblove.xcodeproj/project.pbxproj b/platform/xcode/liblove.xcodeproj/project.pbxproj index 07c676ba9..e7b11a9bb 100644 --- a/platform/xcode/liblove.xcodeproj/project.pbxproj +++ b/platform/xcode/liblove.xcodeproj/project.pbxproj @@ -880,8 +880,6 @@ FABDA9A62552448300B5C523 /* b2_polygon_contact.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA92F2552448200B5C523 /* b2_polygon_contact.h */; }; FABDA9A72552448300B5C523 /* b2_motor_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9302552448200B5C523 /* b2_motor_joint.cpp */; }; FABDA9A82552448300B5C523 /* b2_motor_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9302552448200B5C523 /* b2_motor_joint.cpp */; }; - FABDA9A92552448300B5C523 /* b2_rope_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9312552448200B5C523 /* b2_rope_joint.cpp */; }; - FABDA9AA2552448300B5C523 /* b2_rope_joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9312552448200B5C523 /* b2_rope_joint.cpp */; }; FABDA9AB2552448300B5C523 /* b2_world.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9322552448200B5C523 /* b2_world.cpp */; }; FABDA9AC2552448300B5C523 /* b2_world.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9322552448200B5C523 /* b2_world.cpp */; }; FABDA9AD2552448300B5C523 /* b2_island.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABDA9332552448200B5C523 /* b2_island.cpp */; }; @@ -940,7 +938,6 @@ FABDA9E22552448300B5C523 /* b2_growable_stack.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA95E2552448200B5C523 /* b2_growable_stack.h */; }; FABDA9E32552448300B5C523 /* b2_draw.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA95F2552448200B5C523 /* b2_draw.h */; }; FABDA9E42552448300B5C523 /* b2_collision.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9602552448200B5C523 /* b2_collision.h */; }; - FABDA9E52552448300B5C523 /* b2_rope_joint.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9612552448200B5C523 /* b2_rope_joint.h */; }; FABDA9E62552448300B5C523 /* b2_api.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9622552448200B5C523 /* b2_api.h */; }; FABDA9E72552448300B5C523 /* b2_chain_shape.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9632552448200B5C523 /* b2_chain_shape.h */; }; FABDA9E82552448300B5C523 /* b2_gear_joint.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9642552448200B5C523 /* b2_gear_joint.h */; }; @@ -1862,7 +1859,6 @@ FABDA92E2552448200B5C523 /* b2_wheel_joint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_wheel_joint.cpp; sourceTree = ""; }; FABDA92F2552448200B5C523 /* b2_polygon_contact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_polygon_contact.h; sourceTree = ""; }; FABDA9302552448200B5C523 /* b2_motor_joint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_motor_joint.cpp; sourceTree = ""; }; - FABDA9312552448200B5C523 /* b2_rope_joint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_rope_joint.cpp; sourceTree = ""; }; FABDA9322552448200B5C523 /* b2_world.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_world.cpp; sourceTree = ""; }; FABDA9332552448200B5C523 /* b2_island.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_island.cpp; sourceTree = ""; }; FABDA9342552448200B5C523 /* b2_mouse_joint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2_mouse_joint.cpp; sourceTree = ""; }; @@ -1908,7 +1904,6 @@ FABDA95E2552448200B5C523 /* b2_growable_stack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_growable_stack.h; sourceTree = ""; }; FABDA95F2552448200B5C523 /* b2_draw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_draw.h; sourceTree = ""; }; FABDA9602552448200B5C523 /* b2_collision.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_collision.h; sourceTree = ""; }; - FABDA9612552448200B5C523 /* b2_rope_joint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_rope_joint.h; sourceTree = ""; }; FABDA9622552448200B5C523 /* b2_api.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_api.h; sourceTree = ""; }; FABDA9632552448200B5C523 /* b2_chain_shape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_chain_shape.h; sourceTree = ""; }; FABDA9642552448200B5C523 /* b2_gear_joint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_gear_joint.h; sourceTree = ""; }; @@ -3393,7 +3388,6 @@ FABDA95A2552448200B5C523 /* b2_prismatic_joint.h */, FABDA94C2552448200B5C523 /* b2_pulley_joint.h */, FABDA9452552448200B5C523 /* b2_revolute_joint.h */, - FABDA9612552448200B5C523 /* b2_rope_joint.h */, FABDA9472552448200B5C523 /* b2_rope.h */, FABDA9442552448200B5C523 /* b2_settings.h */, FABDA9122552448200B5C523 /* b2_shape.h */, @@ -3450,7 +3444,6 @@ FABDA9362552448200B5C523 /* b2_prismatic_joint.cpp */, FABDA9242552448200B5C523 /* b2_pulley_joint.cpp */, FABDA9202552448200B5C523 /* b2_revolute_joint.cpp */, - FABDA9312552448200B5C523 /* b2_rope_joint.cpp */, FABDA91B2552448200B5C523 /* b2_weld_joint.cpp */, FABDA92E2552448200B5C523 /* b2_wheel_joint.cpp */, FABDA9232552448200B5C523 /* b2_world_callbacks.cpp */, @@ -4164,7 +4157,6 @@ FABDA9E42552448300B5C523 /* b2_collision.h in Headers */, FA41A3CA1C0A1F950084430C /* ASTCHandler.h in Headers */, FADF54041E3D77B500012CC0 /* wrap_Text.h in Headers */, - FABDA9E52552448300B5C523 /* b2_rope_joint.h in Headers */, FA0B7ED31A95902C000E1D17 /* wrap_ThreadModule.h in Headers */, FAC756F61E4F99B400B91289 /* Effect.h in Headers */, FA0B7ADD1A958EA3000E1D17 /* gladfuncs.hpp in Headers */, @@ -4517,7 +4509,6 @@ FA0B7E981A95902C000E1D17 /* Sound.cpp in Sources */, FA0B7E371A95902C000E1D17 /* WheelJoint.cpp in Sources */, FA4F2C0C1DE936ED00CA37D7 /* select.c in Sources */, - FABDA9AA2552448300B5C523 /* b2_rope_joint.cpp in Sources */, FA0B7D8E1A95902C000E1D17 /* ddsHandler.cpp in Sources */, FA0B7DFE1A95902C000E1D17 /* ChainShape.cpp in Sources */, FAE64A892071363100BC7981 /* physfs_archiver_vdf.c in Sources */, @@ -4912,7 +4903,6 @@ FA0B7E361A95902C000E1D17 /* WheelJoint.cpp in Sources */, FADF542F1E3DABF600012CC0 /* SpriteBatch.cpp in Sources */, FA0B7D8D1A95902C000E1D17 /* ddsHandler.cpp in Sources */, - FABDA9A92552448300B5C523 /* b2_rope_joint.cpp in Sources */, FAAA3FD91F64B3AD00F89E99 /* lstrlib.c in Sources */, FA0B7DFD1A95902C000E1D17 /* ChainShape.cpp in Sources */, FA0B79201A958E3B000E1D17 /* delay.cpp in Sources */, diff --git a/src/libraries/box2d/Box2D.h b/src/libraries/box2d/Box2D.h index 516818f82..d7937460e 100644 --- a/src/libraries/box2d/Box2D.h +++ b/src/libraries/box2d/Box2D.h @@ -53,7 +53,6 @@ #include "b2_prismatic_joint.h" #include "b2_pulley_joint.h" #include "b2_revolute_joint.h" -#include "b2_rope_joint.h" #include "b2_weld_joint.h" #include "b2_wheel_joint.h" diff --git a/src/libraries/box2d/b2_rope_joint.h b/src/libraries/box2d/b2_rope_joint.h deleted file mode 100644 index b254b3a22..000000000 --- a/src/libraries/box2d/b2_rope_joint.h +++ /dev/null @@ -1,118 +0,0 @@ -// MIT License - -// Copyright (c) 2019 Erin Catto - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of 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 B2_ROPE_JOINT_H -#define B2_ROPE_JOINT_H - -#include "b2_joint.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. - float 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(float inv_dt) const override; - float GetReactionTorque(float 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(float length) { m_maxLength = length; } - float GetMaxLength() const; - - // Get current length - float GetLength() 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; - float m_maxLength; - float m_length; - float 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; - float m_invMassA; - float m_invMassB; - float m_invIA; - float m_invIB; - float m_mass; -}; - -#endif diff --git a/src/libraries/box2d/dynamics/b2_rope_joint.cpp b/src/libraries/box2d/dynamics/b2_rope_joint.cpp deleted file mode 100644 index ebe800f82..000000000 --- a/src/libraries/box2d/dynamics/b2_rope_joint.cpp +++ /dev/null @@ -1,234 +0,0 @@ -// MIT License - -// Copyright (c) 2019 Erin Catto - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of 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. - -#include "box2d/b2_body.h" -#include "box2d/b2_rope_joint.h" -#include "box2d/b2_time_step.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_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; - float aA = data.positions[m_indexA].a; - b2Vec2 vA = data.velocities[m_indexA].v; - float wA = data.velocities[m_indexA].w; - - b2Vec2 cB = data.positions[m_indexB].c; - float aB = data.positions[m_indexB].a; - b2Vec2 vB = data.velocities[m_indexB].v; - float 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(); - - 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. - float crA = b2Cross(m_rA, m_u); - float crB = b2Cross(m_rB, m_u); - float 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; - float wA = data.velocities[m_indexA].w; - b2Vec2 vB = data.velocities[m_indexB].v; - float 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); - float C = m_length - m_maxLength; - float Cdot = b2Dot(m_u, vpB - vpA); - - // Predictive constraint. - if (C < 0.0f) - { - Cdot += data.step.inv_dt * C; - } - - float impulse = -m_mass * Cdot; - float 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; - float aA = data.positions[m_indexA].a; - b2Vec2 cB = data.positions[m_indexB].c; - float 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; - - m_length = u.Normalize(); - float C = m_length - m_maxLength; - - C = b2Clamp(C, 0.0f, b2_maxLinearCorrection); - - float 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 m_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(float inv_dt) const -{ - b2Vec2 F = (inv_dt * m_impulse) * m_u; - return F; -} - -float b2RopeJoint::GetReactionTorque(float inv_dt) const -{ - B2_NOT_USED(inv_dt); - return 0.0f; -} - -float b2RopeJoint::GetMaxLength() const -{ - return m_maxLength; -} - -float b2RopeJoint::GetLength() const -{ - return m_length; -} - -void b2RopeJoint::Dump() -{ - int32 indexA = m_bodyA->m_islandIndex; - int32 indexB = m_bodyB->m_islandIndex; - - b2Dump(" b2RopeJointDef jd;\n"); - b2Dump(" jd.bodyA = bodies[%d];\n", indexA); - b2Dump(" jd.bodyB = bodies[%d];\n", indexB); - b2Dump(" jd.collideConnected = bool(%d);\n", m_collideConnected); - b2Dump(" jd.localAnchorA.Set(%.9g, %.9g);\n", m_localAnchorA.x, m_localAnchorA.y); - b2Dump(" jd.localAnchorB.Set(%.9g, %.9g);\n", m_localAnchorB.x, m_localAnchorB.y); - b2Dump(" jd.maxLength = %.9g;\n", m_maxLength); - b2Dump(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); -} diff --git a/src/modules/physics/box2d/RopeJoint.cpp b/src/modules/physics/box2d/RopeJoint.cpp index a0055ec49..e84b397ff 100644 --- a/src/modules/physics/box2d/RopeJoint.cpp +++ b/src/modules/physics/box2d/RopeJoint.cpp @@ -38,7 +38,7 @@ RopeJoint::RopeJoint(Body *body1, Body *body2, float x1, float y1, float x2, flo : Joint(body1, body2) , joint(NULL) { - b2RopeJointDef def; + b2DistanceJointDef def; def.bodyA = body1->body; def.bodyB = body2->body; body1->getLocalPoint(x1, y1, x1, y1); @@ -49,7 +49,7 @@ RopeJoint::RopeJoint(Body *body1, Body *body2, float x1, float y1, float x2, flo def.localAnchorB.y = Physics::scaleDown(y2); def.maxLength = Physics::scaleDown(maxLength); def.collideConnected = collideConnected; - joint = (b2RopeJoint *)createJoint(&def); + joint = (b2DistanceJoint *)createJoint(&def); } RopeJoint::~RopeJoint() diff --git a/src/modules/physics/box2d/RopeJoint.h b/src/modules/physics/box2d/RopeJoint.h index f7809d9bb..a059a44a2 100644 --- a/src/modules/physics/box2d/RopeJoint.h +++ b/src/modules/physics/box2d/RopeJoint.h @@ -56,7 +56,7 @@ public: private: // The Box2D RopeJoint object. - b2RopeJoint *joint; + b2DistanceJoint *joint; }; } // box2d From 0b06d0d1f9defaef0353523012acf918cbc01954 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Fri, 13 Nov 2020 17:57:30 -0400 Subject: [PATCH 47/57] macOS: turn code signing off completely on x64 Previously it was using ad-hoc ('sign to run locally') signing, which breaks on macOS 10.14 and older when a .love is put in the Resources subfolder. Ad-hoc is necessary on Apple Silicon but not x64, if real code signing isn't used. --- platform/xcode/love.xcodeproj/project.pbxproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/xcode/love.xcodeproj/project.pbxproj b/platform/xcode/love.xcodeproj/project.pbxproj index ced4c310d..b91a13301 100644 --- a/platform/xcode/love.xcodeproj/project.pbxproj +++ b/platform/xcode/love.xcodeproj/project.pbxproj @@ -438,7 +438,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = "OS X AppIcon"; CODE_SIGN_ENTITLEMENTS = love.entitlements; - CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_IDENTITY = ""; COMBINE_HIDPI_IMAGES = YES; ENABLE_HARDENED_RUNTIME = YES; FRAMEWORK_SEARCH_PATHS = ( @@ -471,7 +471,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = "OS X AppIcon"; CODE_SIGN_ENTITLEMENTS = love.entitlements; - CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_IDENTITY = ""; COMBINE_HIDPI_IMAGES = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_HARDENED_RUNTIME = YES; @@ -893,7 +893,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = "OS X AppIcon"; CODE_SIGN_ENTITLEMENTS = love.entitlements; - CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_IDENTITY = ""; COMBINE_HIDPI_IMAGES = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_HARDENED_RUNTIME = YES; From cfda1f54258833e02c45cfaa6b331e5f55a5fed8 Mon Sep 17 00:00:00 2001 From: Miku AuahDark Date: Thu, 3 Dec 2020 13:34:23 +0800 Subject: [PATCH 48/57] PhysFS: Fix compile error when targetting Windows ARM64 --- src/libraries/physfs/physfs_lzmasdk.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libraries/physfs/physfs_lzmasdk.h b/src/libraries/physfs/physfs_lzmasdk.h index c86972e57..b1463fdea 100644 --- a/src/libraries/physfs/physfs_lzmasdk.h +++ b/src/libraries/physfs/physfs_lzmasdk.h @@ -508,7 +508,8 @@ MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned mem #if defined(MY_CPU_AMD64) \ || defined(_M_IA64) \ || defined(__AARCH64EL__) \ - || defined(__AARCH64EB__) + || defined(__AARCH64EB__) \ + || defined(_M_ARM64) #define MY_CPU_64BIT #endif @@ -529,7 +530,7 @@ MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned mem #define MY_CPU_32BIT #endif -#if defined(_WIN32) && defined(_M_ARM) +#if defined(_WIN32) && (defined(_M_ARM) || defined(_M_ARM64)) #define MY_CPU_ARM_LE #endif From fc69bcce03b1b52b84431589692929ec695221a7 Mon Sep 17 00:00:00 2001 From: Miku AuahDark Date: Thu, 3 Dec 2020 13:42:53 +0800 Subject: [PATCH 49/57] dr_mp3: Fix Windows ARM64 compilation. Based on lieff/minimp3@0d0c452dc76f744ceea4782de17bb735163cdee4. dr_mp3 is based on minimp3, thus have similar structure. Ieally, we should update dr_mp3, but it makes the commit noisy and dr_mp3 is updated often so an update to dr_mp3 should be done before new LOVE releases. --- src/libraries/dr/dr_mp3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/dr/dr_mp3.h b/src/libraries/dr/dr_mp3.h index c876c064b..4fe386abe 100644 --- a/src/libraries/dr/dr_mp3.h +++ b/src/libraries/dr/dr_mp3.h @@ -617,7 +617,7 @@ end: return g_have_simd - 1; #endif } -#elif defined(__ARM_NEON) || defined(__aarch64__) +#elif defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64) #include #define DRMP3_HAVE_SSE 0 #define DRMP3_HAVE_SIMD 1 From c8eeefba519898b7f951c348a1180fbcf01e4976 Mon Sep 17 00:00:00 2001 From: Miku AuahDark Date: Thu, 3 Dec 2020 13:48:25 +0800 Subject: [PATCH 50/57] dr_flac: Ensure NEON codepath is taken for Windows ARM64 Patch based on mackron/dr_libs@5c6b5b1638c625d82ac350ce4c1e7581cc10f292 --- src/libraries/dr/dr_flac.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/dr/dr_flac.h b/src/libraries/dr/dr_flac.h index c30574ebe..fdbd3492c 100644 --- a/src/libraries/dr/dr_flac.h +++ b/src/libraries/dr/dr_flac.h @@ -1020,7 +1020,7 @@ drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterator* pIter, #define DRFLAC_X64 #elif defined(__i386) || defined(_M_IX86) #define DRFLAC_X86 -#elif defined(__arm__) || defined(_M_ARM) +#elif defined(__arm__) || defined(_M_ARM) || defined(_M_ARM64) #define DRFLAC_ARM #endif From 6301b690afd8cb47e39aee217abebbd75384c16e Mon Sep 17 00:00:00 2001 From: Miku AuahDark Date: Thu, 3 Dec 2020 13:53:41 +0800 Subject: [PATCH 51/57] Ensure LOVE_SIMD_NEON is defined when compiling for Windows ARM64 --- src/common/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/config.h b/src/common/config.h index 69be99fbd..3d588cbca 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -71,7 +71,7 @@ #endif // NEON instructions. -#if defined(__ARM_NEON) +#if defined(__ARM_NEON) || defined(_M_ARM64) # define LOVE_SIMD_NEON #endif From 67ea81f739c31f2aefefb978b1d7cca8062422d8 Mon Sep 17 00:00:00 2001 From: Miku AuahDark Date: Thu, 3 Dec 2020 14:29:03 +0800 Subject: [PATCH 52/57] Don't look for (and link with) OpenGL for Megasource build --- CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c9d29ddc8..5dbbe8172 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,8 +65,6 @@ if(POLICY CMP0072) cmake_policy(SET CMP0072 NEW) endif() -find_package(OpenGL) - if(MEGA) # LOVE_MSVC_DLLS contains runtime DLLs that should be bundled with the love # binary (in e.g. the installer). Example: msvcp140.dll. @@ -88,7 +86,6 @@ if(MEGA) set(LOVE_LINK_DIRS ${SDL_LINK_DIR}) set(LOVE_LINK_LIBRARIES - ${OPENGL_gl_LIBRARY} ${MEGA_FREETYPE} ${MEGA_LIBOGG} ${MEGA_LIBVORBISFILE} From 74edaf8fba0b3749dd016352f1a70c26586342e1 Mon Sep 17 00:00:00 2001 From: cigumo Date: Tue, 8 Dec 2020 23:13:52 -0300 Subject: [PATCH 53/57] adds iOS audio interruption handling and recovery --- src/common/ios.h | 6 +++ src/common/ios.mm | 81 ++++++++++++++++++++++++++++++ src/modules/audio/Audio.h | 6 +++ src/modules/audio/null/Audio.cpp | 9 ++++ src/modules/audio/null/Audio.h | 3 ++ src/modules/audio/openal/Audio.cpp | 23 +++++++++ src/modules/audio/openal/Audio.h | 2 + 7 files changed, 130 insertions(+) diff --git a/src/common/ios.h b/src/common/ios.h index 8e436d94b..7c103f9c2 100644 --- a/src/common/ios.h +++ b/src/common/ios.h @@ -78,6 +78,12 @@ bool setAudioMixWithOthers(bool mixEnabled); **/ bool hasBackgroundMusic(); +/** + * Registers notifications to handle and restore audio interruptions + **/ +void initAudioSessionInterruptionHandler(); +void destroyAudioSessionInterruptionHandler(); + /** * Gets the area in the window that is safe for UI to render to (not covered by * the status bar, notch, etc.) diff --git a/src/common/ios.mm b/src/common/ios.mm index 198c50786..66ad349b8 100644 --- a/src/common/ios.mm +++ b/src/common/ios.mm @@ -28,6 +28,8 @@ #import #import +#include "modules/audio/Audio.h" + #include #include @@ -200,6 +202,53 @@ static int dropFileEventFilter(void *userdata, SDL_Event *event) } } +@interface LoveAudioInterruptionListener : NSObject +@end + +@implementation LoveAudioInterruptionListener + ++ (id) shared +{ + // thread-safe singleton + static dispatch_once_t pred = 0; + __strong static id _shared = nil; + dispatch_once(&pred, ^{ + _shared = [[self alloc] init]; + }); + return _shared; +} + +- (void)audioSessionInterruption:(NSNotification *)note +{ + @synchronized (self) { + auto audio = love::Module::getInstance(love::Module::M_AUDIO); + if (!audio) { + NSLog(@"LoveAudioInterruptionListener could not get love audio module"); + return; + } + NSNumber *type = note.userInfo[AVAudioSessionInterruptionTypeKey]; + if (type.unsignedIntegerValue == AVAudioSessionInterruptionTypeBegan) { + audio->pauseContext(); + } else { + audio->resumeContext(); + } + } +} + +- (void)applicationBecameActive:(NSNotification *)note +{ + @synchronized (self) { + auto audio = love::Module::getInstance(love::Module::M_AUDIO); + if (!audio) { + NSLog(@"ERROR:could not get love audio module"); + return; + } + audio->resumeContext(); + } +} + +@end + namespace love { namespace ios @@ -376,6 +425,38 @@ bool hasBackgroundMusic() } } +void initAudioSessionInterruptionHandler() +{ + @autoreleasepool + { + AVAudioSession *session = [AVAudioSession sharedInstance]; + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + + [center addObserver:[LoveAudioInterruptionListener shared] + selector:@selector(audioSessionInterruption:) + name:AVAudioSessionInterruptionNotification + object:session]; + + // An interruption end notification is not guaranteed to be sent if + // we were previously interrupted... resuming if needed when the app + // becomes active seems to be the way to go. + [center addObserver:[LoveAudioInterruptionListener shared] + selector:@selector(applicationBecameActive:) + name:UIApplicationDidBecomeActiveNotification + object:nil]; + + [center addObserver:[LoveAudioInterruptionListener shared] + selector:@selector(applicationBecameActive:) + name:UIApplicationWillEnterForegroundNotification + object:nil]; + } +} + +void destroyAudioSessionInterruptionHandler() +{ + [[NSNotificationCenter defaultCenter] removeObserver:[LoveAudioInterruptionListener shared]]; +} + Rect getSafeArea(SDL_Window *window) { @autoreleasepool diff --git a/src/modules/audio/Audio.h b/src/modules/audio/Audio.h index 7a72882be..d2bfc4132 100644 --- a/src/modules/audio/Audio.h +++ b/src/modules/audio/Audio.h @@ -291,6 +291,12 @@ public: **/ static bool setMixWithSystem(bool mix); + /** + * Pause/resume audio context + */ + virtual void pauseContext() = 0; + virtual void resumeContext() = 0; + private: static StringMap::Entry distanceModelEntries[]; diff --git a/src/modules/audio/null/Audio.cpp b/src/modules/audio/null/Audio.cpp index f64d6cf7e..8fa9eee8d 100644 --- a/src/modules/audio/null/Audio.cpp +++ b/src/modules/audio/null/Audio.cpp @@ -203,6 +203,15 @@ bool Audio::isEFXsupported() const return false; } +void Audio::pauseContext() +{ +} + +void Audio::resumeContext() +{ +} + + } // null } // audio } // love diff --git a/src/modules/audio/null/Audio.h b/src/modules/audio/null/Audio.h index cecc2f7dc..367c25bad 100644 --- a/src/modules/audio/null/Audio.h +++ b/src/modules/audio/null/Audio.h @@ -86,6 +86,9 @@ public: int getMaxSourceEffects() const; bool isEFXsupported() const; + void pauseContext(); + void resumeContext(); + private: float volume; DistanceModel distanceModel; diff --git a/src/modules/audio/openal/Audio.cpp b/src/modules/audio/openal/Audio.cpp index 75a23d54f..d62a272ac 100644 --- a/src/modules/audio/openal/Audio.cpp +++ b/src/modules/audio/openal/Audio.cpp @@ -26,6 +26,10 @@ #include #include +#ifdef LOVE_IOS +#include "common/ios.h" +#endif + namespace love { namespace audio @@ -189,10 +193,18 @@ Audio::Audio() poolThread = new PoolThread(pool); poolThread->start(); + +#ifdef LOVE_IOS + love::ios::initAudioSessionInterruptionHandler(); +#endif + } Audio::~Audio() { +#ifdef LOVE_IOS + love::ios::destroyAudioSessionInterruptionHandler(); +#endif poolThread->setFinish(); poolThread->wait(); @@ -293,6 +305,17 @@ std::vector Audio::pause() return Source::pause(pool); } +void Audio::pauseContext() +{ + alcMakeContextCurrent(nullptr); +} + +void Audio::resumeContext() +{ + if (context && alcGetCurrentContext() != context) + alcMakeContextCurrent(context); +} + void Audio::setVolume(float volume) { alListenerf(AL_GAIN, volume); diff --git a/src/modules/audio/openal/Audio.h b/src/modules/audio/openal/Audio.h index 18fcae6d2..75e6a26bc 100644 --- a/src/modules/audio/openal/Audio.h +++ b/src/modules/audio/openal/Audio.h @@ -95,6 +95,8 @@ public: void pause(love::audio::Source *source); void pause(const std::vector &sources); std::vector pause(); + void pauseContext(); + void resumeContext(); void setVolume(float volume); float getVolume() const; From 81272ba5b5b3f2c7dbddc9020ec3597b93f08069 Mon Sep 17 00:00:00 2001 From: Miku AuahDark Date: Tue, 15 Dec 2020 10:25:38 +0800 Subject: [PATCH 54/57] Only use pinned memory on AMD GPUs. As per in Discord, for some reason Intel driver in Linux(?) expose pinned memory extension and causes driver crash in one test case. --- src/modules/graphics/opengl/StreamBuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/graphics/opengl/StreamBuffer.cpp b/src/modules/graphics/opengl/StreamBuffer.cpp index 10eed951e..278be76bf 100644 --- a/src/modules/graphics/opengl/StreamBuffer.cpp +++ b/src/modules/graphics/opengl/StreamBuffer.cpp @@ -499,7 +499,7 @@ love::graphics::StreamBuffer *CreateStreamBuffer(BufferType mode, size_t size) { // AMD's pinned memory seems to be faster than persistent mapping, // on AMD GPUs. - if (GLAD_AMD_pinned_memory) + if (GLAD_AMD_pinned_memory && gl.getVendor() == OpenGL::VENDOR_AMD) { try { From a1861a8ff4e5c2b1d080dc22ed22d41cf761786d Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Mon, 21 Dec 2020 13:36:29 -0400 Subject: [PATCH 55/57] Don't allow calling Texture:generateMipmaps on depth/stencil textures --- src/modules/graphics/Texture.cpp | 6 ++++++ src/modules/graphics/opengl/Graphics.cpp | 5 +---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/modules/graphics/Texture.cpp b/src/modules/graphics/Texture.cpp index 8897b8de7..7b9345f9b 100644 --- a/src/modules/graphics/Texture.cpp +++ b/src/modules/graphics/Texture.cpp @@ -233,6 +233,9 @@ Texture::Texture(const Settings &settings, const Slices *slices) if (mipmapsMode != MIPMAPS_NONE) mipmapCount = getTotalMipmapCount(pixelWidth, pixelHeight, depth); + if (mipmapsMode == MIPMAPS_AUTO && isPixelFormatDepthStencil(format)) + throw love::Exception("Automatic mipmap generation cannot be used for depth/stencil textures."); + if (pixelWidth <= 0 || pixelHeight <= 0 || layers <= 0 || depth <= 0) throw love::Exception("Texture dimensions must be greater than 0."); @@ -498,6 +501,9 @@ void Texture::generateMipmaps() if (isPixelFormatCompressed(format)) throw love::Exception("generateMipmaps cannot be called on a compressed Texture."); + if (isPixelFormatDepthStencil(format)) + throw love::Exception("generateMipmaps cannot be called on a depth/stencil Texture."); + generateMipmapsInternal(); } diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index 463f88eb3..56ff3aa60 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -717,15 +717,12 @@ void Graphics::endPass() } } + // generateMipmaps can't be used for depth/stencil textures. for (const auto &rt : rts.colors) { if (rt.texture->getMipmapsMode() == Texture::MIPMAPS_AUTO && rt.mipmap == 0) rt.texture->generateMipmaps(); } - - int dsmipmap = rts.depthStencil.mipmap; - if (depthstencil != nullptr && depthstencil->getMipmapsMode() == Texture::MIPMAPS_AUTO && dsmipmap == 0) - depthstencil->generateMipmaps(); } void Graphics::clear(OptionalColorf c, OptionalInt stencil, OptionalDouble depth) From 1f9d98263d20d529ad3ee82b6a1dc8196e51ed27 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Tue, 22 Dec 2020 19:23:02 -0400 Subject: [PATCH 56/57] Refactor Buffer internals. Allows buffers created with love.graphics.newBuffer to only allocate VRAM data. Previously they had a copy of their contents in RAM. Also makes it easier to implement Buffers in other graphics APIs and to implement more types of Buffers in the future. --- CMakeLists.txt | 1 + .../xcode/liblove.xcodeproj/project.pbxproj | 4 + src/common/Range.h | 83 ++++++ src/modules/graphics/Buffer.cpp | 1 - src/modules/graphics/Buffer.h | 43 +--- src/modules/graphics/Graphics.cpp | 2 +- src/modules/graphics/Mesh.cpp | 238 +++++++----------- src/modules/graphics/Mesh.h | 51 ++-- src/modules/graphics/ParticleSystem.cpp | 6 +- src/modules/graphics/SpriteBatch.cpp | 38 ++- src/modules/graphics/SpriteBatch.h | 12 +- src/modules/graphics/Text.cpp | 136 +++++----- src/modules/graphics/Text.h | 19 +- src/modules/graphics/opengl/Buffer.cpp | 210 +++++++--------- src/modules/graphics/opengl/Buffer.h | 15 +- src/modules/graphics/opengl/Graphics.cpp | 29 ++- src/modules/graphics/opengl/Graphics.h | 6 + src/modules/graphics/opengl/Shader.cpp | 31 +-- src/modules/graphics/opengl/Shader.h | 2 - src/modules/graphics/wrap_Buffer.cpp | 19 +- src/modules/graphics/wrap_Graphics.cpp | 28 ++- src/modules/graphics/wrap_Mesh.cpp | 47 ++-- src/modules/graphics/wrap_SpriteBatch.cpp | 6 +- 23 files changed, 504 insertions(+), 523 deletions(-) create mode 100644 src/common/Range.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c9d29ddc8..c9cb24246 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -266,6 +266,7 @@ set(LOVE_SRC_COMMON src/common/Optional.h src/common/pixelformat.cpp src/common/pixelformat.h + src/common/Range.h src/common/Reference.cpp src/common/Reference.h src/common/runtime.cpp diff --git a/platform/xcode/liblove.xcodeproj/project.pbxproj b/platform/xcode/liblove.xcodeproj/project.pbxproj index e7b11a9bb..bde7abb15 100644 --- a/platform/xcode/liblove.xcodeproj/project.pbxproj +++ b/platform/xcode/liblove.xcodeproj/project.pbxproj @@ -829,6 +829,7 @@ FAB2D5AA1AABDD8A008224A4 /* TrueTypeRasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB2D5A81AABDD8A008224A4 /* TrueTypeRasterizer.cpp */; }; FAB2D5AB1AABDD8A008224A4 /* TrueTypeRasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB2D5A81AABDD8A008224A4 /* TrueTypeRasterizer.cpp */; }; FAB2D5AC1AABDD8A008224A4 /* TrueTypeRasterizer.h in Headers */ = {isa = PBXBuildFile; fileRef = FAB2D5A91AABDD8A008224A4 /* TrueTypeRasterizer.h */; }; + FAB922C6257D99EF0035DAD6 /* Range.h in Headers */ = {isa = PBXBuildFile; fileRef = FAB922C3257D99EF0035DAD6 /* Range.h */; }; FABDA9762552448200B5C523 /* b2_joint.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9112552448200B5C523 /* b2_joint.h */; }; FABDA9772552448200B5C523 /* b2_shape.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9122552448200B5C523 /* b2_shape.h */; }; FABDA9782552448200B5C523 /* b2_block_allocator.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDA9132552448200B5C523 /* b2_block_allocator.h */; }; @@ -1828,6 +1829,7 @@ FAB17BF41ABFC4B100F9BA27 /* lz4hc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lz4hc.h; sourceTree = ""; }; FAB2D5A81AABDD8A008224A4 /* TrueTypeRasterizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TrueTypeRasterizer.cpp; sourceTree = ""; }; FAB2D5A91AABDD8A008224A4 /* TrueTypeRasterizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrueTypeRasterizer.h; sourceTree = ""; }; + FAB922C3257D99EF0035DAD6 /* Range.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Range.h; sourceTree = ""; }; FABDA9112552448200B5C523 /* b2_joint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_joint.h; sourceTree = ""; }; FABDA9122552448200B5C523 /* b2_shape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_shape.h; sourceTree = ""; }; FABDA9132552448200B5C523 /* b2_block_allocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2_block_allocator.h; sourceTree = ""; }; @@ -2223,6 +2225,7 @@ FAF1889C1E9DA834008C1479 /* Optional.h */, FA9D8DCF1DEB56C3002CD881 /* pixelformat.cpp */, FA9D8DD01DEB56C3002CD881 /* pixelformat.h */, + FAB922C3257D99EF0035DAD6 /* Range.h */, FA0B790C1A958E3B000E1D17 /* Reference.cpp */, FA0B790D1A958E3B000E1D17 /* Reference.h */, FA0B790E1A958E3B000E1D17 /* runtime.cpp */, @@ -4158,6 +4161,7 @@ FA41A3CA1C0A1F950084430C /* ASTCHandler.h in Headers */, FADF54041E3D77B500012CC0 /* wrap_Text.h in Headers */, FA0B7ED31A95902C000E1D17 /* wrap_ThreadModule.h in Headers */, + FAB922C6257D99EF0035DAD6 /* Range.h in Headers */, FAC756F61E4F99B400B91289 /* Effect.h in Headers */, FA0B7ADD1A958EA3000E1D17 /* gladfuncs.hpp in Headers */, FAF1405D1E20934C00F898D2 /* intermediate.h in Headers */, diff --git a/src/common/Range.h b/src/common/Range.h new file mode 100644 index 000000000..d150919f8 --- /dev/null +++ b/src/common/Range.h @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2006-2020 LOVE Development Team + * + * 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. + **/ + +#pragma once + +#include +#include +#include + +namespace love +{ + +struct Range +{ + size_t first; + size_t last; + + Range() + : first(std::numeric_limits::max()) + , last(0) + {} + + Range(size_t offset, size_t size) + : first(offset) + , last(offset + size - 1) + {} + + bool isValid() const { return first <= last; } + + void invalidate() + { + first = std::numeric_limits::max(); + last = 0; + } + + size_t getMin() const { return first; } + size_t getMax() const { return last; } + + size_t getOffset() const { return first; } + size_t getSize() const { return (last - first) + 1; } + + bool contains(const Range &other) const + { + return first <= other.first && last >= other.last; + } + + void encapsulate(size_t index) + { + first = std::min(first, index); + last = std::max(last, index); + } + + void encapsulate(size_t offset, size_t size) + { + first = std::min(first, offset); + last = std::max(last, offset + size - 1); + } + + void encapsulate(const Range &other) + { + first = std::min(first, other.first); + last = std::max(last, other.last); + } +}; + +} // love diff --git a/src/modules/graphics/Buffer.cpp b/src/modules/graphics/Buffer.cpp index 6124e515d..c9c3f8a5f 100644 --- a/src/modules/graphics/Buffer.cpp +++ b/src/modules/graphics/Buffer.cpp @@ -34,7 +34,6 @@ Buffer::Buffer(Graphics *gfx, const Settings &settings, const std::vector Mesh::getDefaultVertexFormat() love::Type Mesh::type("Mesh", &Drawable::type); Mesh::Mesh(graphics::Graphics *gfx, const std::vector &vertexformat, const void *data, size_t datasize, PrimitiveType drawmode, BufferUsage usage) - : vertexBuffer(nullptr) - , vertexCount(0) - , vertexStride(0) - , vertexScratchBuffer(nullptr) - , indexBuffer(nullptr) - , useIndexBuffer(false) - , indexCount(0) - , indexDataType(INDEX_UINT16) - , primitiveType(drawmode) - , rangeStart(-1) - , rangeCount(-1) + : primitiveType(drawmode) { - Buffer::Settings settings(Buffer::TYPEFLAG_VERTEX, Buffer::MAP_EXPLICIT_RANGE_MODIFY | Buffer::MAP_READ, usage); - vertexBuffer.set(gfx->newBuffer(settings, vertexformat, data, datasize, 0), Acquire::NORETAIN); + try + { + vertexData = new uint8[datasize]; + } + catch (std::exception &) + { + throw love::Exception("Out of memory"); + } + + memcpy(vertexData, data, datasize); + + Buffer::Settings settings(Buffer::TYPEFLAG_VERTEX, usage); + vertexBuffer.set(gfx->newBuffer(settings, vertexformat, vertexData, datasize, 0), Acquire::NORETAIN); vertexCount = vertexBuffer->getArrayLength(); vertexStride = vertexBuffer->getArrayStride(); @@ -68,27 +69,17 @@ Mesh::Mesh(graphics::Graphics *gfx, const std::vector & setupAttachedAttributes(); indexDataType = getIndexDataTypeFromMax(vertexCount); - - vertexScratchBuffer = new char[vertexStride]; } Mesh::Mesh(graphics::Graphics *gfx, const std::vector &vertexformat, int vertexcount, PrimitiveType drawmode, BufferUsage usage) - : vertexBuffer(nullptr) - , vertexCount((size_t) vertexcount) - , vertexStride(0) - , vertexScratchBuffer(nullptr) - , indexBuffer(nullptr) - , useIndexBuffer(false) - , indexCount(0) + : vertexCount((size_t) vertexcount) , indexDataType(getIndexDataTypeFromMax(vertexcount)) , primitiveType(drawmode) - , rangeStart(-1) - , rangeCount(-1) { if (vertexcount <= 0) throw love::Exception("Invalid number of vertices (%d).", vertexcount); - Buffer::Settings settings(Buffer::TYPEFLAG_VERTEX, Buffer::MAP_EXPLICIT_RANGE_MODIFY | Buffer::MAP_READ, usage); + Buffer::Settings settings(Buffer::TYPEFLAG_VERTEX, usage); vertexBuffer.set(gfx->newBuffer(settings, vertexformat, nullptr, 0, vertexcount), Acquire::NORETAIN); vertexStride = vertexBuffer->getArrayStride(); @@ -96,25 +87,21 @@ Mesh::Mesh(graphics::Graphics *gfx, const std::vector & setupAttachedAttributes(); - memset(vertexBuffer->map(), 0, vertexBuffer->getSize()); - vertexBuffer->setMappedRangeModified(0, vertexBuffer->getSize()); - vertexBuffer->unmap(); + try + { + vertexData = new uint8[vertexBuffer->getSize()]; + } + catch (std::exception &) + { + throw love::Exception("Out of memory"); + } - vertexScratchBuffer = new char[vertexStride]; + memset(vertexData, 0, vertexBuffer->getSize()); + vertexBuffer->fill(0, vertexBuffer->getSize(), vertexData); } Mesh::Mesh(const std::vector &attributes, PrimitiveType drawmode) - : vertexBuffer(nullptr) - , vertexCount(0) - , vertexStride(0) - , vertexScratchBuffer(nullptr) - , indexBuffer(nullptr) - , useIndexBuffer(false) - , indexCount(0) - , indexDataType(INDEX_UINT16) - , primitiveType(drawmode) - , rangeStart(-1) - , rangeCount(-1) + : primitiveType(drawmode) { if (attributes.size() == 0) throw love::Exception("At least one buffer attribute must be specified in this constructor."); @@ -139,7 +126,9 @@ Mesh::Mesh(const std::vector &attributes, PrimitiveType d Mesh::~Mesh() { - delete vertexScratchBuffer; + delete vertexData; + if (indexData != nullptr) + free(indexData); } void Mesh::setupAttachedAttributes() @@ -151,7 +140,7 @@ void Mesh::setupAttachedAttributes() if (getAttachedAttributeIndex(name) != -1) throw love::Exception("Duplicate vertex attribute name: %s", name.c_str()); - attachedAttributes.push_back({name, vertexBuffer, (int) i, STEP_PER_VERTEX, true}); + attachedAttributes.push_back({name, vertexBuffer, nullptr, (int) i, STEP_PER_VERTEX, true}); } } @@ -166,89 +155,19 @@ int Mesh::getAttachedAttributeIndex(const std::string &name) const return -1; } -void Mesh::setVertex(size_t vertindex, const void *data, size_t datasize) +void *Mesh::checkVertexDataOffset(size_t vertindex, size_t *byteoffset) { if (vertindex >= vertexCount) throw love::Exception("Invalid vertex index: %ld", vertindex + 1); - if (vertexBuffer.get() == nullptr) - throw love::Exception("setVertex can only be called on a Mesh which owns its own vertex buffer."); + if (vertexData == nullptr) + throw love::Exception("Mesh must own its own vertex buffer."); size_t offset = vertindex * vertexStride; - size_t size = std::min(datasize, vertexStride); - uint8 *bufferdata = (uint8 *) vertexBuffer->map(); - memcpy(bufferdata + offset, data, size); - - vertexBuffer->setMappedRangeModified(offset, size); -} - -size_t Mesh::getVertex(size_t vertindex, void *data, size_t datasize) -{ - if (vertindex >= vertexCount) - throw love::Exception("Invalid vertex index: %ld", vertindex + 1); - - if (vertexBuffer.get() == nullptr) - throw love::Exception("getVertex can only be called on a Mesh which owns its own vertex buffer."); - - size_t offset = vertindex * vertexStride; - size_t size = std::min(datasize, vertexStride); - - // We're relying on map() returning read/write data... ew. - const uint8 *bufferdata = (const uint8 *) vertexBuffer->map(); - memcpy(data, bufferdata + offset, size); - - return size; -} - -void *Mesh::getVertexScratchBuffer() -{ - return vertexScratchBuffer; -} - -void Mesh::setVertexAttribute(size_t vertindex, int attribindex, const void *data, size_t datasize) -{ - if (vertindex >= vertexCount) - throw love::Exception("Invalid vertex index: %ld", vertindex + 1); - - if (attribindex >= (int) vertexFormat.size()) - throw love::Exception("Invalid vertex attribute index: %d", attribindex + 1); - - if (vertexBuffer.get() == nullptr) - throw love::Exception("setVertexAttribute can only be called on a Mesh which owns its own vertex buffer."); - - const auto &member = vertexFormat[attribindex]; - - size_t offset = vertindex * vertexStride + member.offset; - size_t size = std::min(datasize, member.info.size); - - uint8 *bufferdata = (uint8 *) vertexBuffer->map(); - memcpy(bufferdata + offset, data, size); - - vertexBuffer->setMappedRangeModified(offset, size); -} - -size_t Mesh::getVertexAttribute(size_t vertindex, int attribindex, void *data, size_t datasize) -{ - if (vertindex >= vertexCount) - throw love::Exception("Invalid vertex index: %ld", vertindex + 1); - - if (attribindex >= (int) vertexFormat.size()) - throw love::Exception("Invalid vertex attribute index: %d", attribindex + 1); - - if (vertexBuffer.get() == nullptr) - throw love::Exception("getVertexAttribute can only be called on a Mesh which owns its own vertex buffer."); - - const auto &member = vertexFormat[attribindex]; - - size_t offset = vertindex * vertexStride + member.offset; - size_t size = std::min(datasize, member.info.size); - - // We're relying on map() returning read/write data... ew. - const uint8 *bufferdata = (const uint8 *) vertexBuffer->map(); - memcpy(data, bufferdata + offset, size); - - return size; + if (byteoffset != nullptr) + *byteoffset = offset; + return vertexData + offset; } size_t Mesh::getVertexCount() const @@ -289,7 +208,7 @@ bool Mesh::isAttributeEnabled(const std::string &name) const return attachedAttributes[index].enabled; } -void Mesh::attachAttribute(const std::string &name, Buffer *buffer, const std::string &attachname, AttributeStep step) +void Mesh::attachAttribute(const std::string &name, Buffer *buffer, Mesh *mesh, const std::string &attachname, AttributeStep step) { if ((buffer->getTypeFlags() & Buffer::TYPEFLAG_VERTEX) == 0) throw love::Exception("Buffer must be created with vertex buffer support to be used as a Mesh vertex attribute."); @@ -309,6 +228,7 @@ void Mesh::attachAttribute(const std::string &name, Buffer *buffer, const std::s newattrib.name = name; newattrib.buffer = buffer; + newattrib.mesh = mesh; newattrib.enabled = oldattrib.buffer.get() ? oldattrib.enabled : true; newattrib.indexInBuffer = buffer->getDataMemberIndex(attachname); newattrib.step = step; @@ -331,7 +251,7 @@ bool Mesh::detachAttribute(const std::string &name) attachedAttributes.erase(attachedAttributes.begin() + index); if (vertexBuffer.get() && vertexBuffer->getDataMemberIndex(name) != -1) - attachAttribute(name, vertexBuffer, name); + attachAttribute(name, vertexBuffer, nullptr, name); return true; } @@ -341,36 +261,49 @@ const std::vector &Mesh::getAttachedAttributes() const return attachedAttributes; } -void *Mesh::mapVertexData() +void *Mesh::getVertexData() const { - return vertexBuffer.get() != nullptr ? vertexBuffer->map() : nullptr; + return vertexData; } -void Mesh::unmapVertexData(size_t modifiedoffset, size_t modifiedsize) +void Mesh::setVertexDataModified(size_t offset, size_t size) { - if (!vertexBuffer.get()) - return; - - vertexBuffer->setMappedRangeModified(modifiedoffset, modifiedsize); - vertexBuffer->unmap(); + if (vertexData != nullptr) + modifiedVertexData.encapsulate(offset, size); } void Mesh::flush() { - if (vertexBuffer.get()) - vertexBuffer->unmap(); + if (vertexBuffer.get() && vertexData != nullptr && modifiedVertexData.isValid()) + { + if (vertexBuffer->getUsage() == BUFFERUSAGE_STREAM) + { + vertexBuffer->fill(0, vertexBuffer->getSize(), vertexData); + } + else + { + size_t offset = modifiedVertexData.getOffset(); + size_t size = modifiedVertexData.getSize(); + vertexBuffer->fill(offset, size, vertexData + offset); + } - if (indexBuffer.get()) - indexBuffer->unmap(); + modifiedVertexData.invalidate(); + } + + if (indexDataModified && indexData != nullptr && indexBuffer != nullptr) + { + indexBuffer->fill(0, indexBuffer->getSize(), indexData); + indexDataModified = false; + } } /** * Copies index data from a vector to a mapped index buffer. **/ template -static void copyToIndexBuffer(const std::vector &indices, Buffer::Mapper &buffermap, size_t maxval) +static void copyToIndexBuffer(const std::vector &indices, void *data, size_t maxval) { - T *elems = (T *) buffermap.data; + T *elems = (T *) data; for (size_t i = 0; i < indices.size(); i++) { @@ -395,7 +328,7 @@ void Mesh::setVertexMap(const std::vector &map) { auto gfx = Module::getInstance(Module::M_GRAPHICS); auto usage = vertexBuffer.get() ? vertexBuffer->getUsage() : BUFFERUSAGE_DYNAMIC; - Buffer::Settings settings(Buffer::TYPEFLAG_INDEX, Buffer::MAP_READ, usage); + Buffer::Settings settings(Buffer::TYPEFLAG_INDEX, usage); indexBuffer.set(gfx->newBuffer(settings, dataformat, nullptr, size, 0), Acquire::NORETAIN); } @@ -405,17 +338,15 @@ void Mesh::setVertexMap(const std::vector &map) if (!indexBuffer || indexCount == 0) return; - Buffer::Mapper ibomap(*indexBuffer); - // Fill the buffer with the index values from the vector. switch (datatype) { case INDEX_UINT16: - copyToIndexBuffer(map, ibomap, maxval); + copyToIndexBuffer(map, indexData, maxval); break; case INDEX_UINT32: default: - copyToIndexBuffer(map, ibomap, maxval); + copyToIndexBuffer(map, indexData, maxval); break; } @@ -430,7 +361,7 @@ void Mesh::setVertexMap(IndexDataType datatype, const void *data, size_t datasiz { auto gfx = Module::getInstance(Module::M_GRAPHICS); auto usage = vertexBuffer.get() ? vertexBuffer->getUsage() : BUFFERUSAGE_DYNAMIC; - Buffer::Settings settings(Buffer::TYPEFLAG_INDEX, Buffer::MAP_READ, usage); + Buffer::Settings settings(Buffer::TYPEFLAG_INDEX, usage); indexBuffer.set(gfx->newBuffer(settings, dataformat, nullptr, datasize, 0), Acquire::NORETAIN); } @@ -470,24 +401,18 @@ bool Mesh::getVertexMap(std::vector &map) const map.clear(); map.reserve(indexCount); - if (!indexBuffer || indexCount == 0) + if (indexData == nullptr || indexCount == 0) return true; - if ((indexBuffer->getMapFlags() & Buffer::MAP_READ) == 0) - return false; - - // We unmap the buffer in Mesh::draw, Mesh::setVertexMap, and Mesh::flush. - void *buffer = indexBuffer->map(); - // Fill the vector from the buffer. switch (indexDataType) { case INDEX_UINT16: - copyFromIndexBuffer(buffer, indexCount, map); + copyFromIndexBuffer(indexData, indexCount, map); break; case INDEX_UINT32: default: - copyFromIndexBuffer(buffer, indexCount, map); + copyFromIndexBuffer(indexData, indexCount, map); break; } @@ -507,6 +432,12 @@ void Mesh::setIndexBuffer(Buffer *buffer) if (buffer != nullptr) indexDataType = getIndexDataType(buffer->getDataMember(0).decl.format); + + if (indexData != nullptr) + { + free(indexData); + indexData = nullptr; + } } Buffer *Mesh::getIndexBuffer() const @@ -583,6 +514,8 @@ void Mesh::drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount) gfx->flushBatchedDraws(); + flush(); + if (Shader::isDefaultActive()) Shader::attachDefault(Shader::STANDARD_DEFAULT); @@ -612,8 +545,8 @@ void Mesh::drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount) if (attributeindex >= 0) { - // Make sure the buffer isn't mapped (sends data to GPU if needed.) - buffer->unmap(); + if (attrib.mesh.get()) + attrib.mesh->flush(); const auto &member = buffer->getDataMember(attrib.indexInBuffer); @@ -637,9 +570,6 @@ void Mesh::drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount) if (useIndexBuffer && indexBuffer != nullptr && indexCount > 0) { - // Make sure the index buffer isn't mapped (sends data to GPU if needed.) - indexBuffer->unmap(); - Graphics::DrawIndexedCommand cmd(&attributes, &buffers, indexBuffer); cmd.primitiveType = primitiveType; diff --git a/src/modules/graphics/Mesh.h b/src/modules/graphics/Mesh.h index 72994f051..b739238a4 100644 --- a/src/modules/graphics/Mesh.h +++ b/src/modules/graphics/Mesh.h @@ -25,6 +25,7 @@ #include "common/int.h" #include "common/math.h" #include "common/StringMap.h" +#include "common/Range.h" #include "Drawable.h" #include "Texture.h" #include "vertex.h" @@ -54,6 +55,7 @@ public: { std::string name; StrongRef buffer; + StrongRef mesh; int indexInBuffer; AttributeStep step; bool enabled; @@ -68,21 +70,10 @@ public: virtual ~Mesh(); /** - * Sets the values of all attributes at a specific vertex index in the Mesh. - * The size of the data must be less than or equal to the total size of all - * vertex attributes. + * Validates a vertex index and whether the Mesh has its own vertex buffer, + * and returns a pointer to the vertex data at the given vertex index. **/ - void setVertex(size_t vertindex, const void *data, size_t datasize); - size_t getVertex(size_t vertindex, void *data, size_t datasize); - void *getVertexScratchBuffer(); - - /** - * Sets the values for a single attribute at a specific vertex index in the - * Mesh. The size of the data must be less than or equal to the size of the - * attribute. - **/ - void setVertexAttribute(size_t vertindex, int attribindex, const void *data, size_t datasize); - size_t getVertexAttribute(size_t vertindex, int attribindex, void *data, size_t datasize); + void *checkVertexDataOffset(size_t vertindex, size_t *byteoffset); /** * Gets the total number of vertices that can be used when drawing the Mesh. @@ -114,13 +105,16 @@ public: /** * Attaches a vertex attribute from another vertex buffer to this Mesh. The * attribute will be used when drawing this Mesh. + * Attributes from other Meshes should also pass in the Mesh as an argument, + * to make sure this Mesh knows to flush the passed in Mesh's data to its + * buffer when drawing. **/ - void attachAttribute(const std::string &name, Buffer *buffer, const std::string &attachname, AttributeStep step = STEP_PER_VERTEX); + void attachAttribute(const std::string &name, Buffer *buffer, Mesh *mesh, const std::string &attachname, AttributeStep step = STEP_PER_VERTEX); bool detachAttribute(const std::string &name); const std::vector &getAttachedAttributes() const; - void *mapVertexData(); - void unmapVertexData(size_t modifiedoffset = 0, size_t modifiedsize = -1); + void *getVertexData() const; + void setVertexDataModified(size_t offset, size_t size); /** * Flushes all modified data to the GPU. @@ -197,23 +191,24 @@ private: // Vertex buffer, for the vertex data. StrongRef vertexBuffer; - size_t vertexCount; - size_t vertexStride; + uint8 *vertexData = nullptr; + Range modifiedVertexData = Range(); - // Block of memory whose size is at least as large as a single vertex. Helps - // avoid memory allocations when using Mesh::setVertex etc. - char *vertexScratchBuffer; + size_t vertexCount = 0; + size_t vertexStride = 0; // Index buffer, for the vertex map. StrongRef indexBuffer; - bool useIndexBuffer; - size_t indexCount; - IndexDataType indexDataType; + uint8 *indexData = nullptr; + bool indexDataModified = false; + bool useIndexBuffer = false; + size_t indexCount = 0; + IndexDataType indexDataType = INDEX_UINT16; - PrimitiveType primitiveType; + PrimitiveType primitiveType = PRIMITIVE_TRIANGLES; - int rangeStart; - int rangeCount; + int rangeStart = -1; + int rangeCount = -1; StrongRef texture; diff --git a/src/modules/graphics/ParticleSystem.cpp b/src/modules/graphics/ParticleSystem.cpp index f074c5d7a..5039d4fdf 100644 --- a/src/modules/graphics/ParticleSystem.cpp +++ b/src/modules/graphics/ParticleSystem.cpp @@ -191,7 +191,7 @@ void ParticleSystem::createBuffers(size_t size) auto gfx = Module::getInstance(Module::M_GRAPHICS); size_t bytes = sizeof(Vertex) * size * 4; - Buffer::Settings settings(Buffer::TYPEFLAG_VERTEX, 0, BUFFERUSAGE_STREAM); + Buffer::Settings settings(Buffer::TYPEFLAG_VERTEX, BUFFERUSAGE_STREAM); auto decl = Buffer::getCommonFormatDeclaration(CommonFormat::XYf_STf_RGBAub); buffer = gfx->newBuffer(settings, decl, nullptr, bytes, 0); } @@ -1043,7 +1043,7 @@ void ParticleSystem::draw(Graphics *gfx, const Matrix4 &m) const Vector2 *positions = texture->getQuad()->getVertexPositions(); const Vector2 *texcoords = texture->getQuad()->getVertexTexCoords(); - Vertex *pVerts = (Vertex *) buffer->map(); + Vertex *pVerts = (Vertex *) buffer->map(Buffer::MAP_WRITE_INVALIDATE, 0, buffer->getSize()); Particle *p = pHead; bool useQuads = !quads.empty(); @@ -1079,7 +1079,7 @@ void ParticleSystem::draw(Graphics *gfx, const Matrix4 &m) p = p->next; } - buffer->unmap(); + buffer->unmap(0, pCount * sizeof(Vertex) * 4); Graphics::TempTransform transform(gfx, m); diff --git a/src/modules/graphics/SpriteBatch.cpp b/src/modules/graphics/SpriteBatch.cpp index 285564f3e..6fd5eaefb 100644 --- a/src/modules/graphics/SpriteBatch.cpp +++ b/src/modules/graphics/SpriteBatch.cpp @@ -48,8 +48,7 @@ SpriteBatch::SpriteBatch(Graphics *gfx, Texture *texture, int size, BufferUsage , colorf(1.0f, 1.0f, 1.0f, 1.0f) , array_buf(nullptr) , vertex_data(nullptr) - , modified_sprite_first(LOVE_INT32_MAX) - , modified_sprite_last(0) + , modified_sprites() , range_start(-1) , range_count(-1) { @@ -74,7 +73,7 @@ SpriteBatch::SpriteBatch(Graphics *gfx, Texture *texture, int size, BufferUsage memset(vertex_data, 0, vertex_size); - Buffer::Settings settings(Buffer::TYPEFLAG_VERTEX, Buffer::MAP_EXPLICIT_RANGE_MODIFY, usage); + Buffer::Settings settings(Buffer::TYPEFLAG_VERTEX, usage); auto decl = Buffer::getCommonFormatDeclaration(vertex_format); array_buf.set(gfx->newBuffer(settings, decl, nullptr, vertex_size, 0), Acquire::NORETAIN); @@ -118,8 +117,7 @@ int SpriteBatch::add(Quad *quad, const Matrix4 &m, int index /*= -1*/) verts[i].color = color; } - modified_sprite_first = std::min(modified_sprite_first, spriteindex); - modified_sprite_last = std::max(modified_sprite_last, spriteindex); + modified_sprites.encapsulate(spriteindex); // Increment counter. if (index == -1) @@ -165,8 +163,7 @@ int SpriteBatch::addLayer(int layer, Quad *quad, const Matrix4 &m, int index) verts[i].color = color; } - modified_sprite_first = std::min(modified_sprite_first, spriteindex); - modified_sprite_last = std::max(modified_sprite_last, spriteindex); + modified_sprites.encapsulate(spriteindex); // Increment counter. if (index == -1) @@ -183,19 +180,17 @@ void SpriteBatch::clear() void SpriteBatch::flush() { - if (modified_sprite_first <= modified_sprite_last) + if (modified_sprites.isValid()) { - size_t offset = modified_sprite_first * vertex_stride * 4; - size_t size = (modified_sprite_last - modified_sprite_first) * vertex_stride * 4; + size_t offset = modified_sprites.getOffset() * vertex_stride * 4; + size_t size = modified_sprites.getSize() * vertex_stride * 4; - // TODO: switch this to fill() once it gets cleaned up. - memcpy(((uint8 *)array_buf->map() + offset), vertex_data + offset, size); + if (array_buf->getUsage() == BUFFERUSAGE_STREAM) + array_buf->fill(0, array_buf->getSize(), vertex_data); + else + array_buf->fill(offset, size, vertex_data + offset); - array_buf->setMappedRangeModified(offset, size); - array_buf->unmap(); - - modified_sprite_first = LOVE_INT32_MAX; - modified_sprite_last = 0; + modified_sprites.invalidate(); } } @@ -249,7 +244,7 @@ void SpriteBatch::setBufferSize(int newsize) throw love::Exception("Out of memory."); auto gfx = Module::getInstance(Module::M_GRAPHICS); - Buffer::Settings settings(array_buf->getTypeFlags(), array_buf->getMapFlags(), array_buf->getUsage()); + Buffer::Settings settings(array_buf->getTypeFlags(), array_buf->getUsage()); auto decl = Buffer::getCommonFormatDeclaration(vertex_format); array_buf.set(gfx->newBuffer(settings, decl, nullptr, vertex_size, 0), Acquire::NORETAIN); @@ -267,7 +262,7 @@ int SpriteBatch::getBufferSize() const return size; } -void SpriteBatch::attachAttribute(const std::string &name, Buffer *buffer) +void SpriteBatch::attachAttribute(const std::string &name, Buffer *buffer, Mesh *mesh) { if ((buffer->getTypeFlags() & Buffer::TYPEFLAG_VERTEX) == 0) throw love::Exception("GraphicsBuffer must be created with vertex buffer support to be used as a SpriteBatch vertex attribute."); @@ -288,6 +283,7 @@ void SpriteBatch::attachAttribute(const std::string &name, Buffer *buffer) throw love::Exception("The specified Buffer does not have a vertex attribute named '%s'", name.c_str()); newattrib.buffer = buffer; + newattrib.mesh = mesh; attached_attributes[name] = newattrib; } @@ -371,8 +367,8 @@ void SpriteBatch::draw(Graphics *gfx, const Matrix4 &m) if (attributeindex >= 0) { - // Make sure the buffer isn't mapped (sends data to GPU if needed.) - buffer->unmap(); + if (it.second.mesh.get()) + it.second.mesh->flush(); const auto &member = buffer->getDataMember(it.second.index); diff --git a/src/modules/graphics/SpriteBatch.h b/src/modules/graphics/SpriteBatch.h index 0266f257f..813bf5d2f 100644 --- a/src/modules/graphics/SpriteBatch.h +++ b/src/modules/graphics/SpriteBatch.h @@ -30,6 +30,7 @@ #include "common/math.h" #include "common/Matrix.h" #include "common/Color.h" +#include "common/Range.h" #include "Drawable.h" #include "Mesh.h" #include "vertex.h" @@ -90,10 +91,13 @@ public: int getBufferSize() const; /** - * Attaches a specific vertex attribute from a Mesh to this SpriteBatch. + * Attaches a specific vertex attribute from a Buffer to this SpriteBatch. * The vertex attribute will be used when drawing the SpriteBatch. + * If the attribute comes from a Mesh, it should be given as an argument as + * well, to make sure the SpriteBatch flushes its data to its Buffer when + * the SpriteBatch is drawn. **/ - void attachAttribute(const std::string &name, Buffer *buffer); + void attachAttribute(const std::string &name, Buffer *buffer, Mesh *mesh); void setDrawRange(int start, int count); void setDrawRange(); @@ -107,6 +111,7 @@ private: struct AttachedAttribute { StrongRef buffer; + StrongRef mesh; int index; }; @@ -134,8 +139,7 @@ private: StrongRef array_buf; uint8 *vertex_data; - int modified_sprite_first; - int modified_sprite_last; + Range modified_sprites; std::unordered_map attached_attributes; diff --git a/src/modules/graphics/Text.cpp b/src/modules/graphics/Text.cpp index 8d3fa6dd5..3fa4d5ff3 100644 --- a/src/modules/graphics/Text.cpp +++ b/src/modules/graphics/Text.cpp @@ -33,14 +33,18 @@ love::Type Text::type("Text", &Drawable::type); Text::Text(Font *font, const std::vector &text) : font(font) , vertexAttributes(Font::vertexFormat, 0) - , vert_offset(0) - , texture_cache_id((uint32) -1) + , vertexData(nullptr) + , modifiedVertices() + , vertOffset(0) + , textureCacheID((uint32) -1) { set(text); } Text::~Text() { + if (vertexData != nullptr) + free(vertexData); } void Text::uploadVertices(const std::vector &vertices, size_t vertoffset) @@ -49,32 +53,40 @@ void Text::uploadVertices(const std::vector &vertices, size_t size_t datasize = vertices.size() * sizeof(Font::GlyphVertex); // If we haven't created a VBO or the vertices are too big, make a new one. - if (datasize > 0 && (!vertex_buffer || (offset + datasize) > vertex_buffer->getSize())) + if (datasize > 0 && (!vertexBuffer || (offset + datasize) > vertexBuffer->getSize())) { // Make it bigger than necessary to reduce potential future allocations. size_t newsize = size_t((offset + datasize) * 1.5); - if (vertex_buffer != nullptr) - newsize = std::max(size_t(vertex_buffer->getSize() * 1.5), newsize); + if (vertexBuffer != nullptr) + newsize = std::max(size_t(vertexBuffer->getSize() * 1.5), newsize); auto gfx = Module::getInstance(Module::M_GRAPHICS); - Buffer::Settings settings(Buffer::TYPEFLAG_VERTEX, 0, BUFFERUSAGE_DYNAMIC); + + Buffer::Settings settings(Buffer::TYPEFLAG_VERTEX, BUFFERUSAGE_DYNAMIC); auto decl = Buffer::getCommonFormatDeclaration(Font::vertexFormat); - Buffer *new_buffer = gfx->newBuffer(settings, decl, nullptr, newsize, 0); + Buffer *newbuffer = gfx->newBuffer(settings, decl, nullptr, newsize, 0); - if (vertex_buffer != nullptr) - vertex_buffer->copyTo(0, vertex_buffer->getSize(), new_buffer, 0); + void *newdata = nullptr; + if (vertexData != nullptr) + newdata = realloc(vertexData, newsize); + else + newdata = malloc(newsize); - vertex_buffer = new_buffer; + if (newdata == nullptr) + throw love::Exception("Out of memory."); + else + vertexData = (uint8 *) newdata; - vertexBuffers.set(0, vertex_buffer, 0); + vertexBuffer = newbuffer; + + vertexBuffers.set(0, vertexBuffer, 0); } - if (vertex_buffer != nullptr && datasize > 0) + if (vertexData != nullptr && datasize > 0) { - uint8 *bufferdata = (uint8 *) vertex_buffer->map(); - memcpy(bufferdata + offset, &vertices[0], datasize); - // We unmap when we draw, to avoid unnecessary full map()/unmap() calls. + memcpy(vertexData + offset, &vertices[0], datasize); + modifiedVertices.encapsulate(offset, datasize); } } @@ -82,85 +94,85 @@ void Text::regenerateVertices() { // If the font's texture cache was invalidated then we need to recreate the // text's vertices, since glyph texcoords might have changed. - if (font->getTextureCacheID() != texture_cache_id) + if (font->getTextureCacheID() != textureCacheID) { - std::vector textdata = text_data; + std::vector textdata = textData; clear(); for (const TextData &t : textdata) addTextData(t); - texture_cache_id = font->getTextureCacheID(); + textureCacheID = font->getTextureCacheID(); } } void Text::addTextData(const TextData &t) { std::vector vertices; - std::vector new_commands; + std::vector newcommands; - Font::TextInfo text_info; + Font::TextInfo textinfo; Colorf constantcolor = Colorf(1.0f, 1.0f, 1.0f, 1.0f); // We only have formatted text if the align mode is valid. if (t.align == Font::ALIGN_MAX_ENUM) - new_commands = font->generateVertices(t.codepoints, constantcolor, vertices, 0.0f, Vector2(0.0f, 0.0f), &text_info); + newcommands = font->generateVertices(t.codepoints, constantcolor, vertices, 0.0f, Vector2(0.0f, 0.0f), &textinfo); else - new_commands = font->generateVerticesFormatted(t.codepoints, constantcolor, t.wrap, t.align, vertices, &text_info); + newcommands = font->generateVerticesFormatted(t.codepoints, constantcolor, t.wrap, t.align, vertices, &textinfo); - size_t voffset = vert_offset; + size_t voffset = vertOffset; // Must be before the early exit below. - if (!t.append_vertices) + if (!t.appendVertices) { voffset = 0; - vert_offset = 0; - draw_commands.clear(); - text_data.clear(); + vertOffset = 0; + drawCommands.clear(); + textData.clear(); } if (vertices.empty()) return; - if (t.use_matrix) + if (t.useMatrix) t.matrix.transformXY(&vertices[0], &vertices[0], (int) vertices.size()); uploadVertices(vertices, voffset); - if (!new_commands.empty()) + if (!newcommands.empty()) { // The start vertex should be adjusted to account for the vertex offset. - for (Font::DrawCommand &cmd : new_commands) + for (Font::DrawCommand &cmd : newcommands) cmd.startvertex += (int) voffset; - auto firstcmd = new_commands.begin(); + auto firstcmd = newcommands.begin(); // If the first draw command in the new list has the same texture as the // last one in the existing list we're building and its vertices are // in-order, we can combine them (saving a draw call.) - if (!draw_commands.empty()) + if (!drawCommands.empty()) { - auto prevcmd = draw_commands.back(); + auto prevcmd = drawCommands.back(); if (prevcmd.texture == firstcmd->texture && (prevcmd.startvertex + prevcmd.vertexcount) == firstcmd->startvertex) { - draw_commands.back().vertexcount += firstcmd->vertexcount; + drawCommands.back().vertexcount += firstcmd->vertexcount; ++firstcmd; } } // Append the new draw commands to the list we're building. - draw_commands.insert(draw_commands.end(), firstcmd, new_commands.end()); + drawCommands.insert(drawCommands.end(), firstcmd, newcommands.end()); } - vert_offset = voffset + vertices.size(); + vertOffset = voffset + vertices.size(); - text_data.push_back(t); - text_data.back().text_info = text_info; + textData.push_back(t); + textData.back().textInfo = textinfo; // Font::generateVertices can invalidate the font's texture cache. - if (font->getTextureCacheID() != texture_cache_id) + if (font->getTextureCacheID() != textureCacheID) regenerateVertices(); } @@ -192,15 +204,15 @@ int Text::addf(const std::vector &text, float wrap, Font::A addTextData({codepoints, wrap, align, {}, true, true, m}); - return (int) text_data.size() - 1; + return (int) textData.size() - 1; } void Text::clear() { - text_data.clear(); - draw_commands.clear(); - texture_cache_id = font->getTextureCacheID(); - vert_offset = 0; + textData.clear(); + drawCommands.clear(); + textureCacheID = font->getTextureCacheID(); + vertOffset = 0; } void Text::setFont(Font *f) @@ -209,7 +221,7 @@ void Text::setFont(Font *f) // Invalidate the texture cache ID since the font is different. We also have // to re-upload all the vertices based on the new font's textures. - texture_cache_id = (uint32) -1; + textureCacheID = (uint32) -1; regenerateVertices(); } @@ -221,28 +233,28 @@ Font *Text::getFont() const int Text::getWidth(int index) const { if (index < 0) - index = std::max((int) text_data.size() - 1, 0); + index = std::max((int) textData.size() - 1, 0); - if (index >= (int) text_data.size()) + if (index >= (int) textData.size()) return 0; - return text_data[index].text_info.width; + return textData[index].textInfo.width; } int Text::getHeight(int index) const { if (index < 0) - index = std::max((int) text_data.size() - 1, 0); + index = std::max((int) textData.size() - 1, 0); - if (index >= (int) text_data.size()) + if (index >= (int) textData.size()) return 0; - return text_data[index].text_info.height; + return textData[index].textInfo.height; } void Text::draw(Graphics *gfx, const Matrix4 &m) { - if (vertex_buffer == nullptr || draw_commands.empty()) + if (vertexBuffer == nullptr || vertexData == nullptr || drawCommands.empty()) return; gfx->flushBatchedDraws(); @@ -254,18 +266,30 @@ void Text::draw(Graphics *gfx, const Matrix4 &m) Shader::current->checkMainTextureType(TEXTURE_2D, false); // Re-generate the text if the Font's texture cache was invalidated. - if (font->getTextureCacheID() != texture_cache_id) + if (font->getTextureCacheID() != textureCacheID) regenerateVertices(); int totalverts = 0; - for (const Font::DrawCommand &cmd : draw_commands) + for (const Font::DrawCommand &cmd : drawCommands) totalverts = std::max(cmd.startvertex + cmd.vertexcount, totalverts); - vertex_buffer->unmap(); // Make sure all pending data is flushed to the GPU. + // Make sure all pending data is uploaded to the GPU. + if (modifiedVertices.isValid()) + { + size_t offset = modifiedVertices.getOffset(); + size_t size = modifiedVertices.getSize(); + + if (vertexBuffer->getUsage() == BUFFERUSAGE_STREAM) + vertexBuffer->fill(0, vertexBuffer->getSize(), vertexData); + else + vertexBuffer->fill(offset, size, vertexData + offset); + + modifiedVertices.invalidate(); + } Graphics::TempTransform transform(gfx, m); - for (const Font::DrawCommand &cmd : draw_commands) + for (const Font::DrawCommand &cmd : drawCommands) gfx->drawQuads(cmd.startvertex / 4, cmd.vertexcount / 4, vertexAttributes, vertexBuffers, cmd.texture); } diff --git a/src/modules/graphics/Text.h b/src/modules/graphics/Text.h index ca55ec44e..424bb0859 100644 --- a/src/modules/graphics/Text.h +++ b/src/modules/graphics/Text.h @@ -22,6 +22,7 @@ // LOVE #include "common/config.h" +#include "common/Range.h" #include "Drawable.h" #include "Font.h" #include "Buffer.h" @@ -73,9 +74,9 @@ private: Font::ColoredCodepoints codepoints; float wrap; Font::AlignMode align; - Font::TextInfo text_info; - bool use_matrix; - bool append_vertices; + Font::TextInfo textInfo; + bool useMatrix; + bool appendVertices; Matrix4 matrix; }; @@ -88,16 +89,18 @@ private: VertexAttributes vertexAttributes; BufferBindings vertexBuffers; - StrongRef vertex_buffer; + StrongRef vertexBuffer; + uint8 *vertexData; + Range modifiedVertices; - std::vector draw_commands; + std::vector drawCommands; - std::vector text_data; + std::vector textData; - size_t vert_offset; + size_t vertOffset; // Used so we know when the font's texture cache is invalidated. - uint32 texture_cache_id; + uint32 textureCacheID; }; // Text diff --git a/src/modules/graphics/opengl/Buffer.cpp b/src/modules/graphics/opengl/Buffer.cpp index 61eb6e61b..43276e59f 100644 --- a/src/modules/graphics/opengl/Buffer.cpp +++ b/src/modules/graphics/opengl/Buffer.cpp @@ -22,6 +22,7 @@ #include "common/Exception.h" #include "graphics/vertex.h" +#include "Graphics.h" #include #include @@ -80,22 +81,26 @@ Buffer::Buffer(love::graphics::Graphics *gfx, const Settings &settings, const st target = OpenGL::getGLBufferType(mapType); - try + if (usage == BUFFERUSAGE_STREAM) + ownsMemoryMap = true; + + std::vector emptydata; + if (settings.zeroInitialize && data == nullptr) { - memoryMap = new char[size]; - } - catch (std::bad_alloc &) - { - throw love::Exception("Out of memory."); + try + { + emptydata.resize(getSize()); + data = emptydata.data(); + } + catch (std::exception &) + { + data = nullptr; + } } - if (data != nullptr) - memcpy(memoryMap, data, size); - - if (!load(data != nullptr)) + if (!load(data)) { unloadVolatile(); - delete[] memoryMap; throw love::Exception("Could not create buffer (out of VRAM?)"); } } @@ -103,7 +108,8 @@ Buffer::Buffer(love::graphics::Graphics *gfx, const Settings &settings, const st Buffer::~Buffer() { unloadVolatile(); - delete[] memoryMap; + if (memoryMap != nullptr && ownsMemoryMap) + free(memoryMap); } bool Buffer::loadVolatile() @@ -111,7 +117,7 @@ bool Buffer::loadVolatile() if (buffer != 0) return true; - return load(true); + return load(nullptr); } void Buffer::unloadVolatile() @@ -125,7 +131,7 @@ void Buffer::unloadVolatile() texture = 0; } -bool Buffer::load(bool restore) +bool Buffer::load(const void *initialdata) { while (glGetError() != GL_NO_ERROR) /* Clear the error buffer. */; @@ -133,11 +139,8 @@ bool Buffer::load(bool restore) glGenBuffers(1, &buffer); gl.bindBuffer(mapType, buffer); - // Copy the old buffer only if 'restore' was requested. - const GLvoid *src = restore ? memoryMap : nullptr; - - // Note that if 'src' is '0', no data will be copied. - glBufferData(target, (GLsizeiptr) getSize(), src, OpenGL::getGLBufferUsage(getUsage())); + // initialdata can be null. + glBufferData(target, (GLsizeiptr) getSize(), initialdata, OpenGL::getGLBufferUsage(getUsage())); if (getTypeFlags() & TYPEFLAG_TEXEL) { @@ -150,137 +153,104 @@ bool Buffer::load(bool restore) return (glGetError() == GL_NO_ERROR); } -void *Buffer::map() -{ - if (mapped) - return memoryMap; - - mapped = true; - - modifiedOffset = 0; - modifiedSize = 0; - isMappedDataModified = false; - - return memoryMap; -} - -void Buffer::unmapStatic(size_t offset, size_t size) +void *Buffer::map(MapType /*map*/, size_t offset, size_t size) { if (size == 0) - return; + return nullptr; - // Upload the mapped data to the buffer. - gl.bindBuffer(mapType, buffer); - glBufferSubData(target, (GLintptr) offset, (GLsizeiptr) size, memoryMap + offset); -} + Range r(offset, size); -void Buffer::unmapStream() -{ - GLenum glusage = OpenGL::getGLBufferUsage(getUsage()); + if (!Range(0, getSize()).contains(r)) + return nullptr; - // "orphan" current buffer to avoid implicit synchronisation on the GPU: - // http://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-AsynchronousBufferTransfers.pdf - gl.bindBuffer(mapType, buffer); - glBufferData(target, (GLsizeiptr) getSize(), nullptr, glusage); + char *data = nullptr; -#if LOVE_WINDOWS - // TODO: Verify that this codepath is a useful optimization. - if (gl.getVendor() == OpenGL::VENDOR_INTEL) - glBufferData(target, (GLsizeiptr) getSize(), memoryMap, glusage); + if (ownsMemoryMap) + { + if (memoryMap == nullptr) + memoryMap = (char *) malloc(getSize()); + data = memoryMap; + } else -#endif - glBufferSubData(target, 0, (GLsizeiptr) getSize(), memoryMap); + { + auto gfx = Module::getInstance(Module::M_GRAPHICS); + data = (char *) gfx->getBufferMapMemory(size); + } + + if (data != nullptr) + { + mapped = true; + mappedRange = r; + if (!ownsMemoryMap) + memoryMap = data; + } + + return data; } -void Buffer::unmap() +void Buffer::unmap(size_t usedoffset, size_t usedsize) { - if (!mapped) + Range r(usedoffset, usedsize); + + if (!mapped || !mappedRange.contains(r)) return; mapped = false; - if ((mapFlags & MAP_EXPLICIT_RANGE_MODIFY) != 0) + // Orphan optimization - see fill(). + if (usage != BUFFERUSAGE_STATIC && mappedRange.first == 0 && mappedRange.getSize() == getSize()) { - if (!isMappedDataModified) - return; - - modifiedOffset = std::min(modifiedOffset, getSize() - 1); - modifiedSize = std::min(modifiedSize, getSize() - modifiedOffset); - } - else - { - modifiedOffset = 0; - modifiedSize = getSize(); + usedoffset = 0; + usedsize = getSize(); } - if (modifiedSize > 0) + char *data = memoryMap + (usedoffset - mappedRange.getOffset()); + + fill(usedoffset, usedsize, data); + + if (!ownsMemoryMap) { - switch (getUsage()) - { - case BUFFERUSAGE_STATIC: - unmapStatic(modifiedOffset, modifiedSize); - break; - case BUFFERUSAGE_STREAM: - unmapStream(); - break; - case BUFFERUSAGE_DYNAMIC: - default: - // It's probably more efficient to treat it like a streaming buffer if - // at least a third of its contents have been modified during the map(). - if (modifiedSize >= getSize() / 3) - unmapStream(); - else - unmapStatic(modifiedOffset, modifiedSize); - break; - } + auto gfx = Module::getInstance(Module::M_GRAPHICS); + gfx->releaseBufferMapMemory(memoryMap); + memoryMap = nullptr; } - - modifiedOffset = 0; - modifiedSize = 0; -} - -void Buffer::setMappedRangeModified(size_t offset, size_t modifiedsize) -{ - if (!mapped || !(mapFlags & MAP_EXPLICIT_RANGE_MODIFY)) - return; - - if (!isMappedDataModified) - { - modifiedOffset = offset; - modifiedSize = modifiedsize; - isMappedDataModified = true; - return; - } - - // We're being conservative right now by internally marking the whole range - // from the start of section a to the end of section b as modified if both - // a and b are marked as modified. - - size_t oldrangeend = modifiedOffset + modifiedSize; - modifiedOffset = std::min(modifiedOffset, offset); - - size_t newrangeend = std::max(offset + modifiedsize, oldrangeend); - modifiedSize = newrangeend - modifiedOffset; } void Buffer::fill(size_t offset, size_t size, const void *data) { - memcpy(memoryMap + offset, data, size); + if (size == 0) + return; - if (mapped) - setMappedRangeModified(offset, size); + size_t buffersize = getSize(); + + if (!Range(0, buffersize).contains(Range(offset, size))) + return; + + GLenum glusage = OpenGL::getGLBufferUsage(usage); + + gl.bindBuffer(mapType, buffer); + + if (usage != BUFFERUSAGE_STATIC && size == buffersize) + { + // "orphan" current buffer to avoid implicit synchronisation on the GPU: + // http://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-AsynchronousBufferTransfers.pdf + gl.bindBuffer(mapType, buffer); + glBufferData(target, (GLsizeiptr) buffersize, nullptr, glusage); + +#if LOVE_WINDOWS + // TODO: Verify that this codepath is a useful optimization. + if (gl.getVendor() == OpenGL::VENDOR_INTEL) + glBufferData(target, (GLsizeiptr) buffersize, data, glusage); + else +#endif + glBufferSubData(target, 0, (GLsizeiptr) buffersize, data); + } else { - gl.bindBuffer(mapType, buffer); glBufferSubData(target, (GLintptr) offset, (GLsizeiptr) size, data); } } -void Buffer::copyTo(size_t offset, size_t size, love::graphics::Buffer *other, size_t otheroffset) -{ - other->fill(otheroffset, size, memoryMap + offset); -} - } // opengl } // graphics } // love diff --git a/src/modules/graphics/opengl/Buffer.h b/src/modules/graphics/opengl/Buffer.h index b0a96bb5f..db0ae85fe 100644 --- a/src/modules/graphics/opengl/Buffer.h +++ b/src/modules/graphics/opengl/Buffer.h @@ -22,6 +22,7 @@ // LOVE #include "common/config.h" +#include "common/Range.h" #include "graphics/Buffer.h" #include "graphics/Volatile.h" @@ -49,19 +50,16 @@ public: bool loadVolatile() override; void unloadVolatile() override; - void *map() override; - void unmap() override; - void setMappedRangeModified(size_t offset, size_t size) override; + void *map(MapType map, size_t offset, size_t size) override; + void unmap(size_t usedoffset, size_t usedsize) override; void fill(size_t offset, size_t size, const void *data) override; ptrdiff_t getHandle() const override { return buffer; }; ptrdiff_t getTexelBufferHandle() const override { return texture; }; - void copyTo(size_t offset, size_t size, love::graphics::Buffer *other, size_t otheroffset) override; - private: - bool load(bool restore); + bool load(const void *initialdata); void unmapStatic(size_t offset, size_t size); void unmapStream(); @@ -77,10 +75,9 @@ private: // A pointer to mapped memory. char *memoryMap = nullptr; + bool ownsMemoryMap = false; - size_t modifiedOffset = 0; - size_t modifiedSize = 0; - bool isMappedDataModified = false; + Range mappedRange; }; // Buffer diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index 56ff3aa60..08ad88b20 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -93,11 +93,22 @@ Graphics::Graphics() , mainVAO(0) , internalBackbufferFBO(0) , requestedBackbufferMSAA(0) + , bufferMapMemory(nullptr) + , bufferMapMemorySize(2 * 1024 * 1024) , defaultBuffers() , supportedFormats() { gl = OpenGL(); + try + { + bufferMapMemory = new char[bufferMapMemorySize]; + } + catch (std::exception &) + { + // Handled in getBufferMapMemory. + } + auto window = getInstance(M_WINDOW); if (window != nullptr) @@ -121,6 +132,7 @@ Graphics::Graphics() Graphics::~Graphics() { + delete[] bufferMapMemory; } const char *Graphics::getName() const @@ -328,7 +340,7 @@ bool Graphics::setMode(int width, int height, int pixelwidth, int pixelheight, b if (capabilities.features[FEATURE_TEXEL_BUFFER] && defaultBuffers[BUFFERTYPE_TEXEL].get() == nullptr) { - Buffer::Settings settings(Buffer::TYPEFLAG_TEXEL, 0, BUFFERUSAGE_STATIC); + Buffer::Settings settings(Buffer::TYPEFLAG_TEXEL, BUFFERUSAGE_STATIC); std::vector format = {{"", DATAFORMAT_FLOAT_VEC4, 0}}; const float texel[] = {0.0f, 0.0f, 0.0f, 1.0f}; @@ -1436,6 +1448,21 @@ void Graphics::setWireframe(bool enable) states.back().wireframe = enable; } +void *Graphics::getBufferMapMemory(size_t size) +{ + // We don't need anything more complicated because get/release calls are + // never interleaved (as of when this comment was written.) + if (bufferMapMemory == nullptr || size > bufferMapMemorySize) + return malloc(size); + return bufferMapMemory; +} + +void Graphics::releaseBufferMapMemory(void *mem) +{ + if (mem != bufferMapMemory) + free(mem); +} + Graphics::Renderer Graphics::getRenderer() const { return GLAD_ES_VERSION_2_0 ? RENDERER_OPENGLES : RENDERER_OPENGL; diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index 40473327c..7f9ef56fd 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -112,6 +112,9 @@ public: // Internal use. void cleanupRenderTexture(love::graphics::Texture *texture); + void *getBufferMapMemory(size_t size); + void releaseBufferMapMemory(void *mem); + private: struct CachedFBOHasher @@ -159,6 +162,9 @@ private: GLuint internalBackbufferFBO; int requestedBackbufferMSAA; + char *bufferMapMemory; + size_t bufferMapMemorySize; + // Only needed for buffer types that can be bound to shaders. StrongRef defaultBuffers[BUFFERTYPE_MAX_ENUM]; diff --git a/src/modules/graphics/opengl/Shader.cpp b/src/modules/graphics/opengl/Shader.cpp index ed5256f10..9f518e204 100644 --- a/src/modules/graphics/opengl/Shader.cpp +++ b/src/modules/graphics/opengl/Shader.cpp @@ -761,30 +761,8 @@ void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffe buffer->retain(); } - bool addbuffertoarray = true; - if (info->buffers[i] != nullptr) - { - Buffer *oldbuffer = info->buffers[i]; - auto it = std::find(buffersToUnmap.begin(), buffersToUnmap.end(), oldbuffer); - if (it != buffersToUnmap.end()) - { - addbuffertoarray = false; - if (buffer != nullptr) - *it = buffer; - else - { - auto last = buffersToUnmap.end() - 1; - *it = *last; - buffersToUnmap.erase(last); - } - } - - oldbuffer->release(); - } - - if (addbuffertoarray && buffer != nullptr) - buffersToUnmap.push_back(buffer); + info->buffers[i]->release(); info->buffers[i] = buffer; @@ -916,13 +894,6 @@ void Shader::updateBuiltinUniforms(love::graphics::Graphics *gfx, int viewportW, GLint location = builtinUniforms[BUILTIN_UNIFORMS_PER_DRAW]; if (location >= 0) glUniform4fv(location, 13, (const GLfloat *) &data); - - // TODO: Find a better place to put this. - // Buffers used in this shader can be mapped by external code without - // unmapping. We need to make sure the data on the GPU is up to date, - // otherwise the shader can read from old data. - for (Buffer *buffer : buffersToUnmap) - buffer->unmap(); } int Shader::getUniformTypeComponents(GLenum type) const diff --git a/src/modules/graphics/opengl/Shader.h b/src/modules/graphics/opengl/Shader.h index 10591744e..393c7fb6c 100644 --- a/src/modules/graphics/opengl/Shader.h +++ b/src/modules/graphics/opengl/Shader.h @@ -119,8 +119,6 @@ private: std::vector> pendingUniformUpdates; - std::vector buffersToUnmap; - float lastPointSize; }; // Shader diff --git a/src/modules/graphics/wrap_Buffer.cpp b/src/modules/graphics/wrap_Buffer.cpp index 9289134f5..e15ccb01b 100644 --- a/src/modules/graphics/wrap_Buffer.cpp +++ b/src/modules/graphics/wrap_Buffer.cpp @@ -186,13 +186,6 @@ Buffer *luax_checkbuffer(lua_State *L, int idx) return luax_checktype(L, idx); } -static int w_Buffer_flush(lua_State *L) -{ - Buffer *t = luax_checkbuffer(L, 1); - t->unmap(); - return 0; -} - static int w_Buffer_setArrayData(lua_State *L) { Buffer *t = luax_checkbuffer(L, 1); @@ -223,12 +216,8 @@ static int w_Buffer_setArrayData(lua_State *L) return luaL_error(L, "Too many array elements (expected at most %d, got %d)", arraylength - startindex, count); size_t datasize = std::min(d->getSize(), count * stride); - char *bytedata = (char *) t->map() + offset; - memcpy(bytedata, d->getData(), datasize); - - t->setMappedRangeModified(offset, datasize); - t->unmap(); + t->fill(offset, datasize, d->getData()); return 0; } @@ -256,7 +245,7 @@ static int w_Buffer_setArrayData(lua_State *L) if (startindex + count > arraylength) return luaL_error(L, "Too many array elements (expected at most %d, got %d)", arraylength - startindex, count); - char *data = (char *) t->map() + offset; + char *data = (char *) t->map(Buffer::MAP_WRITE_INVALIDATE, offset, count * stride); if (tableoftables) { @@ -303,8 +292,7 @@ static int w_Buffer_setArrayData(lua_State *L) } } - t->setMappedRangeModified(offset, count * stride); - t->unmap(); + t->unmap(offset, count * stride); return 0; } @@ -376,7 +364,6 @@ static int w_Buffer_isBufferType(lua_State *L) static const luaL_Reg w_Buffer_functions[] = { - { "flush", w_Buffer_flush }, { "setArrayData", w_Buffer_setArrayData }, { "getElementCount", w_Buffer_getElementCount }, { "getElementStride", w_Buffer_getElementStride }, diff --git a/src/modules/graphics/wrap_Graphics.cpp b/src/modules/graphics/wrap_Graphics.cpp index cd7c64499..713e5b5dd 100644 --- a/src/modules/graphics/wrap_Graphics.cpp +++ b/src/modules/graphics/wrap_Graphics.cpp @@ -1559,7 +1559,7 @@ static void luax_checkbufferformat(lua_State *L, int idx, std::vector &format) +static Buffer *luax_newbuffer(lua_State *L, int idx, Buffer::Settings settings, const std::vector &format) { size_t arraylength = 0; size_t bytesize = 0; @@ -1600,6 +1600,7 @@ static Buffer *luax_newbuffer(lua_State *L, int idx, const Buffer::Settings &set if (len <= 0) luaL_argerror(L, idx, "number of elements must be greater than 0"); arraylength = (size_t) len; + settings.zeroInitialize = true; } Buffer *b = nullptr; @@ -1663,7 +1664,7 @@ static Buffer *luax_newbuffer(lua_State *L, int idx, const Buffer::Settings &set int w_newBuffer(lua_State *L) { - Buffer::Settings settings(0, Buffer::MAP_EXPLICIT_RANGE_MODIFY, BUFFERUSAGE_DYNAMIC); + Buffer::Settings settings(0, BUFFERUSAGE_DYNAMIC); luaL_checktype(L, 3, LUA_TTABLE); @@ -1691,7 +1692,7 @@ int w_newBuffer(lua_State *L) int w_newVertexBuffer(lua_State *L) { - Buffer::Settings settings(Buffer::TYPEFLAG_VERTEX, Buffer::MAP_EXPLICIT_RANGE_MODIFY, BUFFERUSAGE_DYNAMIC); + Buffer::Settings settings(Buffer::TYPEFLAG_VERTEX, BUFFERUSAGE_DYNAMIC); luax_optbuffersettings(L, 3, settings); std::vector format; @@ -1706,7 +1707,7 @@ int w_newVertexBuffer(lua_State *L) int w_newIndexBuffer(lua_State *L) { - Buffer::Settings settings(Buffer::TYPEFLAG_INDEX, Buffer::MAP_EXPLICIT_RANGE_MODIFY, BUFFERUSAGE_DYNAMIC); + Buffer::Settings settings(Buffer::TYPEFLAG_INDEX, BUFFERUSAGE_DYNAMIC); luax_optbuffersettings(L, 3, settings); size_t arraylength = 0; @@ -1747,6 +1748,7 @@ int w_newIndexBuffer(lua_State *L) if (len <= 0) return luaL_argerror(L, 1, "number of elements must be greater than 0"); arraylength = (size_t) len; + settings.zeroInitialize = true; } if (data != nullptr || !lua_isnoneornil(L, 2)) @@ -1953,8 +1955,9 @@ static Mesh *newCustomMesh(lua_State *L) luax_catchexcept(L, [&](){ t = instance()->newMesh(vertexformat, numvertices, drawmode, usage); }); - // Maximum possible data size for a single vertex attribute. - char data[sizeof(float) * 4]; + char *data = (char *) t->getVertexData(); + size_t stride = t->getVertexStride(); + const auto &members = t->getVertexFormat(); for (size_t vertindex = 0; vertindex < numvertices; vertindex++) { @@ -1965,7 +1968,8 @@ static Mesh *newCustomMesh(lua_State *L) int n = 0; for (size_t i = 0; i < vertexformat.size(); i++) { - const auto &info = getDataFormatInfo(vertexformat[i].format); + const auto &member = members[i]; + const auto &info = getDataFormatInfo(member.decl.format); // get vertices[vertindex][n] for (int c = 0; c < info.components; c++) @@ -1974,20 +1978,18 @@ static Mesh *newCustomMesh(lua_State *L) lua_rawgeti(L, -(c + 1), n); } + size_t offset = vertindex * stride + member.offset; + // Fetch the values from Lua and store them in data buffer. - luax_writebufferdata(L, -info.components, vertexformat[i].format, data); + luax_writebufferdata(L, -info.components, member.decl.format, data + offset); lua_pop(L, info.components); - - luax_catchexcept(L, - [&](){ t->setVertexAttribute(vertindex, i, data, sizeof(float) * 4); }, - [&](bool diderror){ if (diderror) t->release(); } - ); } lua_pop(L, 1); // pop vertices[vertindex] } + t->setVertexDataModified(0, stride * numvertices); t->flush(); } diff --git a/src/modules/graphics/wrap_Mesh.cpp b/src/modules/graphics/wrap_Mesh.cpp index 211463033..97c46f240 100644 --- a/src/modules/graphics/wrap_Mesh.cpp +++ b/src/modules/graphics/wrap_Mesh.cpp @@ -67,11 +67,13 @@ int w_Mesh_setVertices(lua_State *L) return luaL_error(L, "Too many vertices (expected at most %d, got %d)", totalverts - vertstart, vertcount); size_t datasize = std::min(d->getSize(), vertcount * stride); - char *bytedata = (char *) t->mapVertexData() + byteoffset; + char *bytedata = (char *) t->getVertexData() + byteoffset; memcpy(bytedata, d->getData(), datasize); - t->unmapVertexData(byteoffset, datasize); + t->setVertexDataModified(byteoffset, datasize); + t->flush(); + return 0; } @@ -88,7 +90,7 @@ int w_Mesh_setVertices(lua_State *L) for (const Buffer::DataMember &member : vertexformat) ncomponents += member.info.components; - char *data = (char *) t->mapVertexData() + byteoffset; + char *data = (char *) t->getVertexData() + byteoffset; for (int i = 0; i < vertcount; i++) { @@ -114,7 +116,9 @@ int w_Mesh_setVertices(lua_State *L) data += stride; } - t->unmapVertexData(byteoffset, vertcount * stride); + t->setVertexDataModified(byteoffset, vertcount * stride); + t->flush(); + return 0; } @@ -126,7 +130,10 @@ int w_Mesh_setVertex(lua_State *L) bool istable = lua_istable(L, 3); const std::vector &vertexformat = t->getVertexFormat(); - char *data = (char *) t->getVertexScratchBuffer(); + + char *data = nullptr; + size_t offset = 0; + luax_catchexcept(L, [&](){ data = (char *) t->checkVertexDataOffset(index, &offset); }); int idx = istable ? 1 : 3; @@ -156,7 +163,7 @@ int w_Mesh_setVertex(lua_State *L) } } - luax_catchexcept(L, [&](){ t->setVertex(index, data, t->getVertexStride()); }); + t->setVertexDataModified(offset, t->getVertexStride()); return 0; } @@ -167,9 +174,8 @@ int w_Mesh_getVertex(lua_State *L) const std::vector &vertexformat = t->getVertexFormat(); - char *data = (char *) t->getVertexScratchBuffer(); - - luax_catchexcept(L, [&](){ t->getVertex(index, data, t->getVertexStride()); }); + const char *data = nullptr; + luax_catchexcept(L, [&](){ data = (const char *) t->checkVertexDataOffset(index, nullptr); }); int n = 0; @@ -195,13 +201,14 @@ int w_Mesh_setVertexAttribute(lua_State *L) const Buffer::DataMember &member = vertexformat[attribindex]; - // Maximum possible size for a single vertex attribute. - char data[sizeof(float) * 4]; + char *data = nullptr; + size_t offset = 0; + luax_catchexcept(L, [&](){ data = (char *) t->checkVertexDataOffset(vertindex, &offset); }); // Fetch the values from Lua and store them in the data buffer. - luax_writebufferdata(L, 4, member.decl.format, data); + luax_writebufferdata(L, 4, member.decl.format, data + member.offset); - luax_catchexcept(L, [&](){ t->setVertexAttribute(vertindex, attribindex, data, sizeof(float) * 4); }); + t->setVertexDataModified(offset + member.offset, member.size); return 0; } @@ -218,12 +225,10 @@ int w_Mesh_getVertexAttribute(lua_State *L) const Buffer::DataMember &member = vertexformat[attribindex]; - // Maximum possible size for a single vertex attribute. - char data[sizeof(float) * 4]; + const char *data = nullptr; + luax_catchexcept(L, [&](){ data = (const char *) t->checkVertexDataOffset(vertindex, nullptr); }); - luax_catchexcept(L, [&](){ t->getVertexAttribute(vertindex, attribindex, data, sizeof(float) * 4); }); - - luax_readbufferdata(L, member.decl.format, data); + luax_readbufferdata(L, member.decl.format, data + member.offset); return member.info.components; } @@ -290,17 +295,17 @@ int w_Mesh_attachAttribute(lua_State *L) const char *name = luaL_checkstring(L, 2); Buffer *buffer = nullptr; + Mesh *mesh = nullptr; if (luax_istype(L, 3, Buffer::type)) { buffer = luax_checktype(L, 3); } else { - Mesh *mesh = luax_checkmesh(L, 3); + mesh = luax_checkmesh(L, 3); buffer = mesh->getVertexBuffer(); if (buffer == nullptr) return luaL_error(L, "Mesh does not have its own vertex buffer."); - luax_markdeprecated(L, "Mesh:attachAttribute(name, mesh, ...)", API_METHOD, DEPRECATED_REPLACED, "Mesh:attachAttribute(name, buffer, ...)"); } AttributeStep step = STEP_PER_VERTEX; @@ -310,7 +315,7 @@ int w_Mesh_attachAttribute(lua_State *L) const char *attachname = luaL_optstring(L, 5, name); - luax_catchexcept(L, [&](){ t->attachAttribute(name, buffer, attachname, step); }); + luax_catchexcept(L, [&](){ t->attachAttribute(name, buffer, mesh, attachname, step); }); return 0; } diff --git a/src/modules/graphics/wrap_SpriteBatch.cpp b/src/modules/graphics/wrap_SpriteBatch.cpp index 981bcb6dc..1c7aa085b 100644 --- a/src/modules/graphics/wrap_SpriteBatch.cpp +++ b/src/modules/graphics/wrap_SpriteBatch.cpp @@ -218,20 +218,20 @@ int w_SpriteBatch_attachAttribute(lua_State *L) const char *name = luaL_checkstring(L, 2); Buffer *buffer = nullptr; + Mesh *mesh = nullptr; if (luax_istype(L, 3, Buffer::type)) { buffer = luax_checktype(L, 3); } else { - Mesh *mesh = luax_checktype(L, 3); + mesh = luax_checktype(L, 3); buffer = mesh->getVertexBuffer(); if (buffer == nullptr) return luaL_error(L, "Mesh does not have its own vertex buffer."); - luax_markdeprecated(L, "SpriteBatch:attachAttribute(name, mesh)", API_METHOD, DEPRECATED_REPLACED, "SpriteBatch:attachAttribute(name, buffer)"); } - luax_catchexcept(L, [&](){ t->attachAttribute(name, buffer); }); + luax_catchexcept(L, [&](){ t->attachAttribute(name, buffer, mesh); }); return 0; } From 140c1f38c0d8ba5291b516897cbb91e2ee110b5b Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Tue, 22 Dec 2020 19:34:23 -0400 Subject: [PATCH 57/57] Minor code style tweaks --- src/common/ios.mm | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/common/ios.mm b/src/common/ios.mm index 66ad349b8..06780e0b1 100644 --- a/src/common/ios.mm +++ b/src/common/ios.mm @@ -220,26 +220,29 @@ static int dropFileEventFilter(void *userdata, SDL_Event *event) - (void)audioSessionInterruption:(NSNotification *)note { - @synchronized (self) { + @synchronized (self) + { auto audio = love::Module::getInstance(love::Module::M_AUDIO); - if (!audio) { + if (!audio) + { NSLog(@"LoveAudioInterruptionListener could not get love audio module"); return; } NSNumber *type = note.userInfo[AVAudioSessionInterruptionTypeKey]; - if (type.unsignedIntegerValue == AVAudioSessionInterruptionTypeBegan) { + if (type.unsignedIntegerValue == AVAudioSessionInterruptionTypeBegan) audio->pauseContext(); - } else { + else audio->resumeContext(); - } } } - (void)applicationBecameActive:(NSNotification *)note { - @synchronized (self) { + @synchronized (self) + { auto audio = love::Module::getInstance(love::Module::M_AUDIO); - if (!audio) { + if (!audio) + { NSLog(@"ERROR:could not get love audio module"); return; } @@ -247,7 +250,7 @@ static int dropFileEventFilter(void *userdata, SDL_Event *event) } } -@end +@end // LoveAudioInterruptionListener namespace love {