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/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) \ diff --git a/CMakeLists.txt b/CMakeLists.txt index 541b0ea14..c955156d5 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} @@ -266,6 +263,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 @@ -1064,130 +1062,80 @@ 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/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_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} ) @@ -1338,7 +1286,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 +1326,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 +1356,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 @@ -1726,6 +1675,7 @@ set(LOVE_LIB_SRC include_directories( src src/libraries + src/libraries/box2D src/modules ${LOVE_INCLUDE_DIRS} ) diff --git a/changes.txt b/changes.txt index 5ae76fc4d..625fe0b63 100644 --- a/changes.txt +++ b/changes.txt @@ -1,3 +1,62 @@ +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 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. +* 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] +-------------------------------- + +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] -------------------------------- diff --git a/extra/appveyor/appveyor.yml b/extra/appveyor/appveyor.yml index a3741bd5a..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 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 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]) 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) diff --git a/platform/xcode/liblove.xcodeproj/project.pbxproj b/platform/xcode/liblove.xcodeproj/project.pbxproj index cd0894d1b..5714c1cef 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 */; }; @@ -860,8 +721,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 */; }; @@ -1035,6 +894,147 @@ 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 */; }; + 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 */; }; + 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 */; }; + 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 */; }; @@ -1402,99 +1402,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 = ""; }; @@ -1913,7 +1820,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 = ""; }; @@ -2037,6 +1943,102 @@ 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 = ""; }; + 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 = ""; }; + 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 = ""; }; + 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 = ""; }; @@ -2123,6 +2125,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 = ""; }; @@ -2336,6 +2340,7 @@ FAF1889C1E9DA834008C1479 /* Optional.h */, FA9D8DCF1DEB56C3002CD881 /* pixelformat.cpp */, FA9D8DD01DEB56C3002CD881 /* pixelformat.h */, + FAB922C3257D99EF0035DAD6 /* Range.h */, FA0B790C1A958E3B000E1D17 /* Reference.cpp */, FA0B790D1A958E3B000E1D17 /* Reference.h */, FA0B790E1A958E3B000E1D17 /* runtime.cpp */, @@ -2361,7 +2366,7 @@ FA0B794D1A958EA3000E1D17 /* libraries */ = { isa = PBXGroup; children = ( - FA0B794E1A958EA3000E1D17 /* Box2D */, + FABDA9102552448200B5C523 /* box2d */, FA0B79B41A958EA3000E1D17 /* ddsparse */, FA522D5023F9FF2A0059EE3C /* dr */, FA0B79B81A958EA3000E1D17 /* enet */, @@ -2384,162 +2389,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 = ( @@ -3708,6 +3557,140 @@ 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 */, + 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 */, + 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 = ( @@ -3787,6 +3770,7 @@ FAF13FC01E20934C00F898D2 /* glslang */ = { isa = PBXGroup; children = ( + FAEC229F2534F25100EBD925 /* build_info.h */, FAF13FC11E20934C00F898D2 /* GenericCodeGen */, FAF13FC41E20934C00F898D2 /* Include */, FAF13FD21E20934C00F898D2 /* MachineIndependent */, @@ -3850,7 +3834,6 @@ FAF13FE61E20934C00F898D2 /* ParseHelper.cpp */, FAF13FE71E20934C00F898D2 /* ParseHelper.h */, FAF13FE81E20934C00F898D2 /* parseVersions.h */, - FA24348021D401CB00B8918A /* pch.cpp */, FA24348321D401CB00B8918A /* pch.h */, FAF13FE91E20934C00F898D2 /* PoolAlloc.cpp */, FAF13FEA1E20934C00F898D2 /* preprocessor */, @@ -3939,6 +3922,7 @@ FAF6C9C623C2DE2900D7B5BC /* InReadableOrder.cpp */, FAF6C9D523C2DE2900D7B5BC /* Logger.cpp */, FAF6C9D723C2DE2900D7B5BC /* Logger.h */, + FAEC22942534EE6700EBD925 /* NonSemanticDebugPrintf.h */, FAF6C9C923C2DE2900D7B5BC /* spirv.hpp */, FAF6C9CA23C2DE2900D7B5BC /* SpvBuilder.cpp */, FAF6C9C223C2DE2900D7B5BC /* SpvBuilder.h */, @@ -3972,6 +3956,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 */, @@ -3985,6 +3970,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 */, @@ -4005,6 +3991,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 */, @@ -4014,27 +4001,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 */, FA18CF1E23DCF67900263725 /* external_interface.h in Headers */, @@ -4044,6 +4033,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 */, @@ -4057,30 +4047,28 @@ FA0B7EDE1A95902D000E1D17 /* Touch.h in Headers */, FAC7CD861FE35E95006A60C7 /* physfs.h in Headers */, FAF6C9E523C2DE2900D7B5BC /* spirv.hpp in Headers */, - FA18CF1F23DCF67900263725 /* image.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 */, FA18CED723DBC6E000263725 /* Shader.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 */, @@ -4095,30 +4083,33 @@ 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 */, @@ -4126,22 +4117,21 @@ FA18CF1623DCF67900263725 /* spirv_parser.hpp 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 */, @@ -4150,15 +4140,12 @@ 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 */, FA18CEE423DBC6E000263725 /* Graphics.h in Headers */, 217DFBE81D9F6D490055D849 /* inet.h in Headers */, FADF53FA1E3C7ACD00012CC0 /* Buffer.h in Headers */, - FA0B7AA61A958EA3000E1D17 /* b2RevoluteJoint.h in Headers */, FA18CF4223DCF67900263725 /* spirv_glsl.hpp in Headers */, FA18CF1C23DCF67900263725 /* internal_interface.hpp in Headers */, FA18CF2523DCF67900263725 /* spirv_cross_parsed_ir.hpp in Headers */, @@ -4166,6 +4153,7 @@ 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 */, @@ -4173,24 +4161,23 @@ FA18CF3923DCF67900263725 /* spirv_msl.hpp 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 */, FA18CF3223DCF67900263725 /* spirv_cfg.hpp 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 */, FA18CF4523DD1A8100263725 /* ShaderStage.h in Headers */, @@ -4198,12 +4185,11 @@ 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 */, @@ -4216,11 +4202,13 @@ FA0B7E531A95902C000E1D17 /* wrap_FrictionJoint.h in Headers */, FA0B7EB71A95902C000E1D17 /* wrap_System.h in Headers */, FA18CF1923DCF67900263725 /* spirv_cross_error_handling.hpp 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 */, @@ -4235,15 +4223,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 */, @@ -4256,29 +4246,35 @@ FA0B7EE71A95902D000E1D17 /* Window.h in Headers */, FA0B7E651A95902C000E1D17 /* wrap_PolygonShape.h in Headers */, FA18CEE323DBC6E000263725 /* Metal.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 */, FA18CF2023DCF67900263725 /* spirv_hlsl.hpp in Headers */, - FA0B7A461A958EA3000E1D17 /* b2EdgeShape.h in Headers */, FA0B7D271A95902C000E1D17 /* wrap_Font.h in Headers */, - FA0B7A761A958EA3000E1D17 /* b2ChainAndPolygonContact.h in Headers */, FA0B7DAA1A95902C000E1D17 /* PVRHandler.h in Headers */, FA18CF3823DCF67900263725 /* spirv_cross_c.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 */, @@ -4294,38 +4290,33 @@ 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 */, FA18CF1D23DCF67900263725 /* sampler.hpp 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 */, FA18CF2423DCF67900263725 /* spirv_cpp.hpp 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 */, @@ -4335,8 +4326,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 */, @@ -4345,10 +4334,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 */, @@ -4360,14 +4347,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 */, @@ -4377,10 +4361,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 */, @@ -4394,11 +4378,13 @@ FA18CF1A23DCF67900263725 /* barrier.hpp 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 */, FA0B7ED31A95902C000E1D17 /* wrap_ThreadModule.h in Headers */, - FA0B7A511A958EA3000E1D17 /* b2GrowableStack.h in Headers */, + FAB922C6257D99EF0035DAD6 /* Range.h in Headers */, FAC756F61E4F99B400B91289 /* Effect.h in Headers */, FA0B7ADD1A958EA3000E1D17 /* gladfuncs.hpp in Headers */, FAF1405D1E20934C00F898D2 /* intermediate.h in Headers */, @@ -4491,6 +4477,7 @@ 217DFBEB1D9F6D490055D849 /* ltn12.lua in Resources */, 217DFBF41D9F6D490055D849 /* mime.lua in Resources */, 217DFBE31D9F6D490055D849 /* headers.lua in Resources */, + FABDA9C52552448300B5C523 /* README.MODIFIED in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4509,13 +4496,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 */, @@ -4526,21 +4513,22 @@ 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 */, FA18CF4723DD1A8100263725 /* ShaderStage.mm 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 */, @@ -4548,46 +4536,51 @@ 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 */, - FA24348521D401CB00B8918A /* pch.cpp in Sources */, + FABDA99F2552448300B5C523 /* b2_edge_circle_contact.cpp in Sources */, FA0B7DEC1A95902C000E1D17 /* Cursor.cpp in Sources */, FA18CF2B23DCF67900263725 /* spirv_cross_util.cpp in Sources */, FA0B7D871A95902C000E1D17 /* ImageData.cpp in Sources */, FA18CF3123DCF67900263725 /* spirv_hlsl.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 */, FA18CF3623DCF67900263725 /* spirv_cross_parsed_ir.cpp in Sources */, FA4F2C121DE936FE00CA37D7 /* unixtcp.c in Sources */, @@ -4595,39 +4588,37 @@ FA18CF2323DCF67900263725 /* spirv_cfg.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 */, @@ -4636,21 +4627,18 @@ FA18CF4023DCF67900263725 /* spirv_parser.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 */, @@ -4658,7 +4646,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 */, @@ -4683,16 +4671,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 */, @@ -4701,51 +4690,51 @@ 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 */, FA18CF3423DCF67900263725 /* spirv_cpp.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 */, @@ -4754,24 +4743,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 */, 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 */, FA18CEEA23DBC8D400263725 /* Buffer.mm 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 */, @@ -4780,31 +4765,29 @@ FA0B7ADF1A958EA3000E1D17 /* lodepng.cpp in Sources */, FAF140761E20934C00F898D2 /* IntermTraverse.cpp in Sources */, FA0B7E8C1A95902C000E1D17 /* FLACDecoder.cpp in Sources */, - FA0B7A421A958EA3000E1D17 /* b2CircleShape.cpp in Sources */, FA18CF2923DCF67900263725 /* spirv_msl.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 */, FA18CEE223DBC6E000263725 /* Graphics.mm 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 */, FA18CEDF23DBC6E000263725 /* Shader.mm in Sources */, FA0B7CF51A95902C000E1D17 /* File.cpp in Sources */, @@ -4818,10 +4801,12 @@ 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 */, FA18CF2D23DCF67900263725 /* spirv_cross.cpp in Sources */, @@ -4829,12 +4814,13 @@ 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 */, FA18CF1823DCF67900263725 /* spirv_glsl.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 */, @@ -4845,7 +4831,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 */, FA18CEDD23DBC6E000263725 /* Metal.mm in Sources */, FAE64A822071363100BC7981 /* physfs_archiver_grp.c in Sources */, @@ -4862,28 +4847,25 @@ 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 */, FA18CED923DBC6E000263725 /* StreamBuffer.mm 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 */, @@ -4892,13 +4874,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 */, @@ -4924,12 +4909,12 @@ 217DFC031D9F6D490055D849 /* timeout.c in Sources */, FA18CF2623DCF67900263725 /* spirv_reflect.cpp 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 */, @@ -4941,9 +4926,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 */, FA18CF2C23DCF67900263725 /* spirv_cross.cpp in Sources */, @@ -4952,11 +4938,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 */, @@ -4966,29 +4952,33 @@ 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 */, FA18CF2223DCF67900263725 /* spirv_cfg.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 */, - FA24348421D401CB00B8918A /* pch.cpp in Sources */, FA0B7E3F1A95902C000E1D17 /* wrap_ChainShape.cpp in Sources */, FA18CF3023DCF67900263725 /* spirv_hlsl.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 */, FA18CEDC23DBC6E000263725 /* Metal.mm 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 */, @@ -4997,15 +4987,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 */, @@ -5014,20 +5003,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 */, @@ -5038,7 +5028,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 */, @@ -5050,6 +5039,7 @@ FA18CED823DBC6E000263725 /* StreamBuffer.mm 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 */, @@ -5058,20 +5048,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 */, @@ -5087,7 +5074,6 @@ FA18CEDE23DBC6E000263725 /* Shader.mm 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 */, @@ -5100,16 +5086,17 @@ FADF53F81E3C7ACD00012CC0 /* Buffer.cpp in Sources */, FA0B7DD91A95902C000E1D17 /* RandomGenerator.cpp in Sources */, FAF1409A1E20934C00F898D2 /* propagateNoContraction.cpp in Sources */, - FA0B7A9B1A958EA3000E1D17 /* b2MouseJoint.cpp in Sources */, FA18CEE123DBC6E000263725 /* Graphics.mm 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 */, @@ -5117,38 +5104,38 @@ 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 */, FA18CF3523DCF67900263725 /* spirv_cross_parsed_ir.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 */, @@ -5156,13 +5143,13 @@ FA0B7E301A95902C000E1D17 /* Shape.cpp in Sources */, FA93C4541F315B960087CCD4 /* FormatHandler.cpp in Sources */, FA0B7E481A95902C000E1D17 /* wrap_DistanceJoint.cpp in Sources */, - FA0B7A8F1A958EA3000E1D17 /* b2FrictionJoint.cpp in Sources */, FA18CF2E23DCF67900263725 /* spirv_cross_c.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 */, FA18CF2A23DCF67900263725 /* spirv_cross_util.cpp in Sources */, FAC7CD8C1FE35E95006A60C7 /* physfs_archiver_qpak.c in Sources */, @@ -5171,17 +5158,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 */, FAAA3FD91F64B3AD00F89E99 /* lstrlib.c in Sources */, FA0B7DFD1A95902C000E1D17 /* ChainShape.cpp in Sources */, FA0B79201A958E3B000E1D17 /* delay.cpp in Sources */, FA18CF1723DCF67900263725 /* spirv_glsl.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 */, FA18CF3323DCF67900263725 /* spirv_cpp.cpp in Sources */, FA0B7E061A95902C000E1D17 /* DistanceJoint.cpp in Sources */, @@ -5193,21 +5176,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 */, @@ -5224,6 +5204,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 */, @@ -5236,34 +5217,35 @@ 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 */, FA18CEE923DBC8D400263725 /* Buffer.mm 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 */, @@ -5273,7 +5255,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 */, @@ -5284,35 +5265,37 @@ 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 */, FA18CEEF23DC9B3E00263725 /* Texture.mm 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/platform/xcode/love.xcodeproj/project.pbxproj b/platform/xcode/love.xcodeproj/project.pbxproj index 9116a4e00..d6ee7621f 100644 --- a/platform/xcode/love.xcodeproj/project.pbxproj +++ b/platform/xcode/love.xcodeproj/project.pbxproj @@ -434,7 +434,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 = ( @@ -468,7 +468,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; @@ -894,7 +894,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; diff --git a/readme.md b/readme.md index f35f13463..74b37d122 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 ------------ @@ -92,7 +92,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 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/common/config.h b/src/common/config.h index 05741f59b..96d9931f6 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 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 648b56c61..095f570b1 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,56 @@ 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 // LoveAudioInterruptionListener + namespace love { namespace ios @@ -380,6 +432,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/libraries/Box2D/Box2D.h b/src/libraries/Box2D/Box2D.h deleted file mode 100644 index 187046131..000000000 --- a/src/libraries/Box2D/Box2D.h +++ /dev/null @@ -1,68 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef BOX2D_H -#define BOX2D_H - -/** -\mainpage Box2D API Documentation - -\section intro_sec Getting Started - -For documentation please see http://box2d.org/documentation.html - -For discussion please visit http://box2d.org/forum -*/ - -// These include files constitute the main Box2D API - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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/Shapes/b2PolygonShape.h b/src/libraries/Box2D/Collision/Shapes/b2PolygonShape.h deleted file mode 100644 index b19298038..000000000 --- a/src/libraries/Box2D/Collision/Shapes/b2PolygonShape.h +++ /dev/null @@ -1,101 +0,0 @@ -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_POLYGON_SHAPE_H -#define B2_POLYGON_SHAPE_H - -#include - -/// A convex polygon. It is assumed that the interior of the polygon is to -/// the left of each edge. -/// Polygons have a maximum number of vertices equal to b2_maxPolygonVertices. -/// In most cases you should not need many vertices for a convex polygon. -class b2PolygonShape : public b2Shape -{ -public: - b2PolygonShape(); - - /// Implement b2Shape. - b2Shape* Clone(b2BlockAllocator* allocator) const; - - /// @see b2Shape::GetChildCount - int32 GetChildCount() const; - - /// Create a convex hull from the given array of local points. - /// The count must be in the range [3, b2_maxPolygonVertices]. - /// @warning the points may be re-ordered, even if they form a convex polygon - /// @warning collinear points are handled but not removed. Collinear points - /// may lead to poor stacking behavior. - void Set(const b2Vec2* points, int32 count); - - /// Build vertices to represent an axis-aligned box centered on the local origin. - /// @param hx the half-width. - /// @param hy the half-height. - void SetAsBox(float32 hx, float32 hy); - - /// Build vertices to represent an oriented box. - /// @param hx the half-width. - /// @param hy the half-height. - /// @param center the center of the box in local coordinates. - /// @param angle the rotation of the box in local coordinates. - void SetAsBox(float32 hx, float32 hy, const b2Vec2& center, float32 angle); - - /// @see b2Shape::TestPoint - bool TestPoint(const b2Transform& transform, const b2Vec2& p) const; - - /// 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 vertex count. - int32 GetVertexCount() const { return m_count; } - - /// Get a vertex by index. - const b2Vec2& GetVertex(int32 index) const; - - /// Validate convexity. This is a very time consuming operation. - /// @returns true if valid - bool Validate() const; - - b2Vec2 m_centroid; - b2Vec2 m_vertices[b2_maxPolygonVertices]; - b2Vec2 m_normals[b2_maxPolygonVertices]; - int32 m_count; -}; - -inline b2PolygonShape::b2PolygonShape() -{ - m_type = e_polygon; - m_radius = b2_polygonRadius; - m_count = 0; - m_centroid.SetZero(); -} - -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/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/b2Distance.h b/src/libraries/Box2D/Collision/b2Distance.h deleted file mode 100644 index 7bae689d1..000000000 --- a/src/libraries/Box2D/Collision/b2Distance.h +++ /dev/null @@ -1,141 +0,0 @@ - -/* -* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef B2_DISTANCE_H -#define B2_DISTANCE_H - -#include - -class b2Shape; - -/// A distance proxy is used by the GJK algorithm. -/// It encapsulates any shape. -struct b2DistanceProxy -{ - b2DistanceProxy() : m_vertices(NULL), 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); - - /// Get the supporting vertex index in the given direction. - int32 GetSupport(const b2Vec2& d) const; - - /// Get the supporting vertex in the given direction. - const b2Vec2& GetSupportVertex(const b2Vec2& d) const; - - /// Get the vertex count. - int32 GetVertexCount() const; - - /// Get a vertex by index. Used by b2Distance. - const b2Vec2& GetVertex(int32 index) const; - - b2Vec2 m_buffer[2]; - const b2Vec2* m_vertices; - int32 m_count; - float32 m_radius; -}; - -/// Used to warm start b2Distance. -/// Set count to zero on first call. -struct b2SimplexCache -{ - float32 metric; ///< length or area - uint16 count; - uint8 indexA[3]; ///< vertices on shape A - uint8 indexB[3]; ///< vertices on shape B -}; - -/// Input for b2Distance. -/// You have to option to use the shape radii -/// in the computation. Even -struct b2DistanceInput -{ - b2DistanceProxy proxyA; - b2DistanceProxy proxyB; - b2Transform transformA; - b2Transform transformB; - bool useRadii; -}; - -/// Output for b2Distance. -struct b2DistanceOutput -{ - b2Vec2 pointA; ///< closest point on shapeA - b2Vec2 pointB; ///< closest point on shapeB - float32 distance; - int32 iterations; ///< number of GJK iterations used -}; - -/// Compute the closest points between two shapes. Supports any combination of: -/// b2CircleShape, b2PolygonShape, b2EdgeShape. The simplex cache is input/output. -/// On the first call set b2SimplexCache.count to zero. -void b2Distance(b2DistanceOutput* output, - b2SimplexCache* cache, - const b2DistanceInput* input); - - -////////////////////////////////////////////////////////////////////////// - -inline int32 b2DistanceProxy::GetVertexCount() const -{ - return m_count; -} - -inline const b2Vec2& b2DistanceProxy::GetVertex(int32 index) const -{ - b2Assert(0 <= index && index < m_count); - return m_vertices[index]; -} - -inline int32 b2DistanceProxy::GetSupport(const b2Vec2& d) const -{ - int32 bestIndex = 0; - float32 bestValue = b2Dot(m_vertices[0], d); - for (int32 i = 1; i < m_count; ++i) - { - float32 value = b2Dot(m_vertices[i], d); - if (value > bestValue) - { - bestIndex = i; - bestValue = value; - } - } - - return bestIndex; -} - -inline const b2Vec2& b2DistanceProxy::GetSupportVertex(const b2Vec2& d) const -{ - int32 bestIndex = 0; - float32 bestValue = b2Dot(m_vertices[0], d); - for (int32 i = 1; i < m_count; ++i) - { - float32 value = b2Dot(m_vertices[i], d); - if (value > bestValue) - { - bestIndex = i; - bestValue = value; - } - } - - return m_vertices[bestIndex]; -} - -#endif diff --git a/src/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/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/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.cpp b/src/libraries/Box2D/Dynamics/Joints/b2DistanceJoint.cpp deleted file mode 100644 index ba2b6c009..000000000 --- a/src/libraries/Box2D/Dynamics/Joints/b2DistanceJoint.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/* -* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include -#include -#include - -// 1-D constrained system -// m (v2 - v1) = lambda -// v2 + (beta/h) * x1 + gamma * lambda = 0, gamma has units of inverse mass. -// x2 = x1 + h * v2 - -// 1-D mass-damper-spring system -// m (v2 - v1) + h * d * v2 + h * k * - -// C = norm(p2 - p1) - L -// u = (p2 - p1) / norm(p2 - p1) -// Cdot = dot(u, v2 + cross(w2, r2) - v1 - cross(w1, r1)) -// J = [-u -cross(r1, u) u cross(r2, u)] -// K = J * invM * JT -// = invMass1 + invI1 * cross(r1, u)^2 + invMass2 + invI2 * cross(r2, u)^2 - -void b2DistanceJointDef::Initialize(b2Body* b1, b2Body* b2, - const b2Vec2& anchor1, const b2Vec2& anchor2) -{ - bodyA = b1; - bodyB = b2; - localAnchorA = bodyA->GetLocalPoint(anchor1); - localAnchorB = bodyB->GetLocalPoint(anchor2); - b2Vec2 d = anchor2 - anchor1; - length = d.Length(); -} - -b2DistanceJoint::b2DistanceJoint(const b2DistanceJointDef* def) -: b2Joint(def) -{ - m_localAnchorA = def->localAnchorA; - m_localAnchorB = def->localAnchorB; - m_length = def->length; - m_frequencyHz = def->frequencyHz; - m_dampingRatio = def->dampingRatio; - m_impulse = 0.0f; - m_gamma = 0.0f; - m_bias = 0.0f; -} - -void b2DistanceJoint::InitVelocityConstraints(const b2SolverData& data) -{ - m_indexA = m_bodyA->m_islandIndex; - m_indexB = m_bodyB->m_islandIndex; - m_localCenterA = m_bodyA->m_sweep.localCenter; - m_localCenterB = m_bodyB->m_sweep.localCenter; - m_invMassA = m_bodyA->m_invMass; - m_invMassB = m_bodyB->m_invMass; - m_invIA = m_bodyA->m_invI; - m_invIB = m_bodyB->m_invI; - - b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - - b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - b2Rot qA(aA), qB(aB); - - m_rA = b2Mul(qA, m_localAnchorA - m_localCenterA); - m_rB = b2Mul(qB, m_localAnchorB - m_localCenterB); - m_u = cB + m_rB - cA - m_rA; - - // Handle singularity. - float32 length = m_u.Length(); - if (length > b2_linearSlop) - { - m_u *= 1.0f / length; - } - else - { - m_u.Set(0.0f, 0.0f); - } - - float32 crAu = b2Cross(m_rA, m_u); - float32 crBu = b2Cross(m_rB, m_u); - float32 invMass = m_invMassA + m_invIA * crAu * crAu + m_invMassB + m_invIB * crBu * crBu; - - // Compute the effective mass matrix. - m_mass = invMass != 0.0f ? 1.0f / invMass : 0.0f; - - if (m_frequencyHz > 0.0f) - { - float32 C = length - m_length; - - // Frequency - float32 omega = 2.0f * b2_pi * m_frequencyHz; - - // Damping coefficient - float32 d = 2.0f * m_mass * m_dampingRatio * omega; - - // Spring stiffness - float32 k = m_mass * omega * omega; - - // magic formulas - float32 h = data.step.dt; - m_gamma = h * (d + h * k); - m_gamma = m_gamma != 0.0f ? 1.0f / m_gamma : 0.0f; - m_bias = C * h * k * m_gamma; - - invMass += m_gamma; - m_mass = invMass != 0.0f ? 1.0f / invMass : 0.0f; - } - else - { - m_gamma = 0.0f; - m_bias = 0.0f; - } - - if (data.step.warmStarting) - { - // Scale the impulse to support a variable time step. - m_impulse *= data.step.dtRatio; - - b2Vec2 P = m_impulse * m_u; - vA -= m_invMassA * P; - wA -= m_invIA * b2Cross(m_rA, P); - vB += m_invMassB * P; - wB += m_invIB * b2Cross(m_rB, P); - } - else - { - m_impulse = 0.0f; - } - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -void b2DistanceJoint::SolveVelocityConstraints(const b2SolverData& data) -{ - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - // Cdot = dot(u, v + cross(w, r)) - b2Vec2 vpA = vA + b2Cross(wA, m_rA); - b2Vec2 vpB = vB + b2Cross(wB, m_rB); - float32 Cdot = b2Dot(m_u, vpB - vpA); - - float32 impulse = -m_mass * (Cdot + m_bias + m_gamma * m_impulse); - m_impulse += impulse; - - b2Vec2 P = impulse * m_u; - vA -= m_invMassA * P; - wA -= m_invIA * b2Cross(m_rA, P); - vB += m_invMassB * P; - wB += m_invIB * b2Cross(m_rB, P); - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -bool b2DistanceJoint::SolvePositionConstraints(const b2SolverData& data) -{ - if (m_frequencyHz > 0.0f) - { - // There is no position correction for soft distance constraints. - return true; - } - - b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; - b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; - - b2Rot qA(aA), qB(aB); - - b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_localCenterA); - b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); - b2Vec2 u = cB + rB - cA - rA; - - float32 length = u.Normalize(); - float32 C = length - m_length; - C = b2Clamp(C, -b2_maxLinearCorrection, b2_maxLinearCorrection); - - float32 impulse = -m_mass * C; - b2Vec2 P = impulse * u; - - cA -= m_invMassA * P; - aA -= m_invIA * b2Cross(rA, P); - cB += m_invMassB * P; - aB += m_invIB * b2Cross(rB, P); - - data.positions[m_indexA].c = cA; - data.positions[m_indexA].a = aA; - data.positions[m_indexB].c = cB; - data.positions[m_indexB].a = aB; - - return b2Abs(C) < b2_linearSlop; -} - -b2Vec2 b2DistanceJoint::GetAnchorA() const -{ - return m_bodyA->GetWorldPoint(m_localAnchorA); -} - -b2Vec2 b2DistanceJoint::GetAnchorB() const -{ - return m_bodyB->GetWorldPoint(m_localAnchorB); -} - -b2Vec2 b2DistanceJoint::GetReactionForce(float32 inv_dt) const -{ - b2Vec2 F = (inv_dt * m_impulse) * m_u; - return F; -} - -float32 b2DistanceJoint::GetReactionTorque(float32 inv_dt) const -{ - B2_NOT_USED(inv_dt); - return 0.0f; -} - -void b2DistanceJoint::Dump() -{ - int32 indexA = m_bodyA->m_islandIndex; - int32 indexB = m_bodyB->m_islandIndex; - - b2Log(" b2DistanceJointDef jd;\n"); - b2Log(" jd.bodyA = bodies[%d];\n", indexA); - b2Log(" jd.bodyB = bodies[%d];\n", indexB); - b2Log(" jd.collideConnected = bool(%d);\n", m_collideConnected); - b2Log(" jd.localAnchorA.Set(%.15lef, %.15lef);\n", m_localAnchorA.x, m_localAnchorA.y); - b2Log(" jd.localAnchorB.Set(%.15lef, %.15lef);\n", m_localAnchorB.x, m_localAnchorB.y); - b2Log(" jd.length = %.15lef;\n", m_length); - b2Log(" jd.frequencyHz = %.15lef;\n", m_frequencyHz); - b2Log(" jd.dampingRatio = %.15lef;\n", m_dampingRatio); - b2Log(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); -} diff --git a/src/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.cpp b/src/libraries/Box2D/Dynamics/Joints/b2RopeJoint.cpp deleted file mode 100644 index 952ee7a3e..000000000 --- a/src/libraries/Box2D/Dynamics/Joints/b2RopeJoint.cpp +++ /dev/null @@ -1,241 +0,0 @@ -/* -* Copyright (c) 2007-2011 Erin Catto http://www.box2d.org -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ - -#include -#include -#include - - -// Limit: -// C = norm(pB - pA) - L -// u = (pB - pA) / norm(pB - pA) -// Cdot = dot(u, vB + cross(wB, rB) - vA - cross(wA, rA)) -// J = [-u -cross(rA, u) u cross(rB, u)] -// K = J * invM * JT -// = invMassA + invIA * cross(rA, u)^2 + invMassB + invIB * cross(rB, u)^2 - -b2RopeJoint::b2RopeJoint(const b2RopeJointDef* def) -: b2Joint(def) -{ - m_localAnchorA = def->localAnchorA; - m_localAnchorB = def->localAnchorB; - - m_maxLength = def->maxLength; - - m_mass = 0.0f; - m_impulse = 0.0f; - m_state = e_inactiveLimit; - m_length = 0.0f; -} - -void b2RopeJoint::InitVelocityConstraints(const b2SolverData& data) -{ - m_indexA = m_bodyA->m_islandIndex; - m_indexB = m_bodyB->m_islandIndex; - m_localCenterA = m_bodyA->m_sweep.localCenter; - m_localCenterB = m_bodyB->m_sweep.localCenter; - m_invMassA = m_bodyA->m_invMass; - m_invMassB = m_bodyB->m_invMass; - m_invIA = m_bodyA->m_invI; - m_invIB = m_bodyB->m_invI; - - b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - - b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - b2Rot qA(aA), qB(aB); - - m_rA = b2Mul(qA, m_localAnchorA - m_localCenterA); - m_rB = b2Mul(qB, m_localAnchorB - m_localCenterB); - m_u = cB + m_rB - cA - m_rA; - - m_length = m_u.Length(); - - float32 C = m_length - m_maxLength; - if (C > 0.0f) - { - m_state = e_atUpperLimit; - } - else - { - m_state = e_inactiveLimit; - } - - if (m_length > b2_linearSlop) - { - m_u *= 1.0f / m_length; - } - else - { - m_u.SetZero(); - m_mass = 0.0f; - m_impulse = 0.0f; - return; - } - - // Compute effective mass. - float32 crA = b2Cross(m_rA, m_u); - float32 crB = b2Cross(m_rB, m_u); - float32 invMass = m_invMassA + m_invIA * crA * crA + m_invMassB + m_invIB * crB * crB; - - m_mass = invMass != 0.0f ? 1.0f / invMass : 0.0f; - - if (data.step.warmStarting) - { - // Scale the impulse to support a variable time step. - m_impulse *= data.step.dtRatio; - - b2Vec2 P = m_impulse * m_u; - vA -= m_invMassA * P; - wA -= m_invIA * b2Cross(m_rA, P); - vB += m_invMassB * P; - wB += m_invIB * b2Cross(m_rB, P); - } - else - { - m_impulse = 0.0f; - } - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -void b2RopeJoint::SolveVelocityConstraints(const b2SolverData& data) -{ - b2Vec2 vA = data.velocities[m_indexA].v; - float32 wA = data.velocities[m_indexA].w; - b2Vec2 vB = data.velocities[m_indexB].v; - float32 wB = data.velocities[m_indexB].w; - - // Cdot = dot(u, v + cross(w, r)) - b2Vec2 vpA = vA + b2Cross(wA, m_rA); - b2Vec2 vpB = vB + b2Cross(wB, m_rB); - float32 C = m_length - m_maxLength; - float32 Cdot = b2Dot(m_u, vpB - vpA); - - // Predictive constraint. - if (C < 0.0f) - { - Cdot += data.step.inv_dt * C; - } - - float32 impulse = -m_mass * Cdot; - float32 oldImpulse = m_impulse; - m_impulse = b2Min(0.0f, m_impulse + impulse); - impulse = m_impulse - oldImpulse; - - b2Vec2 P = impulse * m_u; - vA -= m_invMassA * P; - wA -= m_invIA * b2Cross(m_rA, P); - vB += m_invMassB * P; - wB += m_invIB * b2Cross(m_rB, P); - - data.velocities[m_indexA].v = vA; - data.velocities[m_indexA].w = wA; - data.velocities[m_indexB].v = vB; - data.velocities[m_indexB].w = wB; -} - -bool b2RopeJoint::SolvePositionConstraints(const b2SolverData& data) -{ - b2Vec2 cA = data.positions[m_indexA].c; - float32 aA = data.positions[m_indexA].a; - b2Vec2 cB = data.positions[m_indexB].c; - float32 aB = data.positions[m_indexB].a; - - b2Rot qA(aA), qB(aB); - - b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_localCenterA); - b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); - b2Vec2 u = cB + rB - cA - rA; - - float32 length = u.Normalize(); - float32 C = length - m_maxLength; - - C = b2Clamp(C, 0.0f, b2_maxLinearCorrection); - - float32 impulse = -m_mass * C; - b2Vec2 P = impulse * u; - - cA -= m_invMassA * P; - aA -= m_invIA * b2Cross(rA, P); - cB += m_invMassB * P; - aB += m_invIB * b2Cross(rB, P); - - data.positions[m_indexA].c = cA; - data.positions[m_indexA].a = aA; - data.positions[m_indexB].c = cB; - data.positions[m_indexB].a = aB; - - return length - m_maxLength < b2_linearSlop; -} - -b2Vec2 b2RopeJoint::GetAnchorA() const -{ - return m_bodyA->GetWorldPoint(m_localAnchorA); -} - -b2Vec2 b2RopeJoint::GetAnchorB() const -{ - return m_bodyB->GetWorldPoint(m_localAnchorB); -} - -b2Vec2 b2RopeJoint::GetReactionForce(float32 inv_dt) const -{ - b2Vec2 F = (inv_dt * m_impulse) * m_u; - return F; -} - -float32 b2RopeJoint::GetReactionTorque(float32 inv_dt) const -{ - B2_NOT_USED(inv_dt); - return 0.0f; -} - -float32 b2RopeJoint::GetMaxLength() const -{ - return m_maxLength; -} - -b2LimitState b2RopeJoint::GetLimitState() const -{ - return m_state; -} - -void b2RopeJoint::Dump() -{ - int32 indexA = m_bodyA->m_islandIndex; - int32 indexB = m_bodyB->m_islandIndex; - - b2Log(" b2RopeJointDef jd;\n"); - b2Log(" jd.bodyA = bodies[%d];\n", indexA); - b2Log(" jd.bodyB = bodies[%d];\n", indexB); - b2Log(" jd.collideConnected = bool(%d);\n", m_collideConnected); - b2Log(" jd.localAnchorA.Set(%.15lef, %.15lef);\n", m_localAnchorA.x, m_localAnchorA.y); - b2Log(" jd.localAnchorB.Set(%.15lef, %.15lef);\n", m_localAnchorB.x, m_localAnchorB.y); - b2Log(" jd.maxLength = %.15lef;\n", m_maxLength); - b2Log(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index); -} diff --git a/src/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/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/Box2D.h b/src/libraries/box2d/Box2D.h new file mode 100644 index 000000000..d7937460e --- /dev/null +++ b/src/libraries/box2d/Box2D.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 BOX2D_H +#define BOX2D_H + +// These include files constitute the main Box2D API + +#include "b2_settings.h" +#include "b2_draw.h" +#include "b2_timer.h" + +#include "b2_chain_shape.h" +#include "b2_circle_shape.h" +#include "b2_edge_shape.h" +#include "b2_polygon_shape.h" + +#include "b2_broad_phase.h" +#include "b2_dynamic_tree.h" + +#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 "b2_distance.h" + +#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_weld_joint.h" +#include "b2_wheel_joint.h" + +#endif 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/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 new file mode 100644 index 000000000..95c12de89 --- /dev/null +++ b/src/libraries/box2d/b2_block_allocator.h @@ -0,0 +1,60 @@ +// 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 "b2_api.h" +#include "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 B2_API 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..f1038202b 100644 --- a/src/libraries/Box2D/Dynamics/b2Body.h +++ b/src/libraries/box2d/b2_body.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_BODY_H #define B2_BODY_H -#include -#include -#include +#include "b2_api.h" +#include "b2_math.h" +#include "b2_shape.h" class b2Fixture; class b2Joint; @@ -41,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 = NULL; position.Set(0.0f, 0.0f); angle = 0.0f; linearVelocity.Set(0.0f, 0.0f); @@ -65,7 +65,7 @@ struct b2BodyDef fixedRotation = false; bullet = false; type = b2_staticBody; - active = true; + enabled = true; gravityScale = 1.0f; } @@ -78,23 +78,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,18 +114,18 @@ 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; + b2BodyUserData userData; /// Scale the gravity applied to this body. - float32 gravityScale; + 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 @@ -142,7 +144,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 +160,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 +172,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 +190,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 +211,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 +223,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 +249,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 +268,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 +333,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. @@ -371,7 +376,7 @@ 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); @@ -380,7 +385,7 @@ public: b2World* GetWorld(); const b2World* GetWorld() const; - /// Dump this body to a log file + /// Dump this body to a file void Dump(); private: @@ -390,7 +395,7 @@ private: friend class b2ContactManager; friend class b2ContactSolver; friend class b2Contact; - + friend class b2DistanceJoint; friend class b2FrictionJoint; friend class b2GearJoint; @@ -411,7 +416,7 @@ private: e_autoSleepFlag = 0x0004, e_bulletFlag = 0x0008, e_fixedRotationFlag = 0x0010, - e_activeFlag = 0x0020, + e_enabledFlag = 0x0020, e_toiFlag = 0x0040 }; @@ -425,7 +430,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 +442,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,18 +457,18 @@ 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; + b2BodyUserData m_userData; }; inline b2BodyType b2Body::GetType() const @@ -481,7 +486,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 +521,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 +536,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 +588,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 +637,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 +663,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 @@ -724,12 +731,7 @@ 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; } @@ -773,7 +775,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 +814,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 +858,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 71% rename from src/libraries/Box2D/Collision/b2BroadPhase.h rename to src/libraries/box2d/b2_broad_phase.h index 0c460cabb..cc882ab47 100644 --- a/src/libraries/Box2D/Collision/b2BroadPhase.h +++ b/src/libraries/box2d/b2_broad_phase.h @@ -1,30 +1,34 @@ -/* -* 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_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; @@ -33,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: @@ -62,7 +66,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 +101,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 +132,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 +164,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 +192,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..da2605d62 --- /dev/null +++ b/src/libraries/box2d/b2_chain_shape.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_CHAIN_SHAPE_H +#define B2_CHAIN_SHAPE_H + +#include "b2_api.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 B2_API 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..5e330f5a7 --- /dev/null +++ b/src/libraries/box2d/b2_circle_shape.h @@ -0,0 +1,67 @@ +// 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_api.h" +#include "b2_shape.h" + +/// A solid circle shape +class B2_API 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 73% rename from src/libraries/Box2D/Collision/b2Collision.h rename to src/libraries/box2d/b2_collision.h index ad023b3ca..4c4592061 100644 --- a/src/libraries/Box2D/Collision/b2Collision.h +++ b/src/libraries/box2d/b2_collision.h @@ -1,27 +1,33 @@ -/* -* 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 +#include "b2_api.h" +#include "b2_math.h" + /// @file /// Structures and functions used for computing contact points, distance /// queries, and TOI queries. @@ -35,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 { @@ -50,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. @@ -66,11 +72,11 @@ 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 - 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 }; @@ -90,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 { @@ -107,19 +113,19 @@ 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 /// 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. @@ -133,33 +139,33 @@ 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; - float32 maxFraction; + float maxFraction; }; /// 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; - float32 fraction; + float fraction; }; /// An axis aligned bounding box. -struct b2AABB +struct B2_API b2AABB { /// Verify that the bounds are sorted. bool IsValid() const; @@ -177,10 +183,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); } @@ -216,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 circle. -void b2CollideEdgeAndPolygon(b2Manifold* manifold, +/// Compute the collision manifold between an edge and a polygon. +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], - const b2Vec2& normal, float32 offset, int32 vertexIndexA); +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/Common/b2Settings.h b/src/libraries/box2d/b2_common.h similarity index 58% rename from src/libraries/Box2D/Common/b2Settings.h rename to src/libraries/box2d/b2_common.h index beaa1d47b..44d9a2625 100644 --- a/src/libraries/Box2D/Common/b2Settings.h +++ b/src/libraries/box2d/b2_common.h @@ -1,43 +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 -#ifndef B2_SETTINGS_H -#define B2_SETTINGS_H +// 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 -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) +void loveAssert(bool test, const char* teststr); #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; -typedef float float32; -typedef double float64; - #define b2_maxFloat FLT_MAX #define b2_epsilon FLT_EPSILON #define b2_pi 3.14159265359f @@ -52,23 +51,19 @@ typedef double float64; /// not change this value. #define b2_maxManifoldPoints 2 -/// The maximum number of vertices on a convex polygon. You cannot increase -/// this too much because b2BlockAllocator has a maximum object size. -#define b2_maxPolygonVertices 8 - /// This is used to fatten AABBs in the dynamic tree. This allows proxies /// to move by a small amount without triggering a tree adjustment. /// This is in meters. -#define b2_aabbExtension 0.1f +#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 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. -#define b2_linearSlop 0.005f +/// 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. @@ -88,21 +83,17 @@ typedef double float64; /// 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 +/// 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 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 +/// 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 @@ -114,7 +105,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 @@ -123,21 +114,15 @@ typedef double float64; #define b2_timeToSleep 0.5f /// A body cannot sleep if its linear velocity is above this tolerance. -#define b2_linearSleepTolerance 0.01f +#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) -// Memory Allocation - -/// Implement this function to use your own memory allocator. -void* b2Alloc(int32 size); - -/// If you implement b2Alloc, you should also implement this function. -void b2Free(void* mem); - -/// Logging function. -void b2Log(const char* string, ...); +/// 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 @@ -149,6 +134,6 @@ struct b2Version }; /// Current version. -extern b2Version b2_version; +extern B2_API b2Version b2_version; #endif diff --git a/src/libraries/Box2D/Dynamics/Contacts/b2Contact.h b/src/libraries/box2d/b2_contact.h similarity index 69% rename from src/libraries/Box2D/Dynamics/Contacts/b2Contact.h rename to src/libraries/box2d/b2_contact.h index 36e31e256..de7541f13 100644 --- a/src/libraries/Box2D/Dynamics/Contacts/b2Contact.h +++ b/src/libraries/box2d/b2_contact.h @@ -1,28 +1,33 @@ -/* -* 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_api.h" +#include "b2_collision.h" +#include "b2_fixture.h" +#include "b2_math.h" +#include "b2_shape.h" class b2Body; class b2Contact; @@ -32,26 +37,32 @@ 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; } +/// 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; @@ -63,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 @@ -74,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: @@ -117,29 +128,39 @@ 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(); + /// 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(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 +178,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 +204,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 +232,13 @@ 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; + float m_restitutionThreshold; - float32 m_tangentSpeed; + float m_tangentSpeed; }; inline b2Manifold* b2Contact::GetManifold() @@ -306,12 +328,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 +343,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 +358,27 @@ inline void b2Contact::ResetRestitution() m_restitution = b2MixRestitution(m_fixtureA->m_restitution, m_fixtureB->m_restitution); } -inline void b2Contact::SetTangentSpeed(float32 speed) +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; } -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..fbd3b4d40 --- /dev/null +++ b/src/libraries/box2d/b2_contact_manager.h @@ -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. + +#ifndef B2_CONTACT_MANAGER_H +#define B2_CONTACT_MANAGER_H + +#include "b2_api.h" +#include "b2_broad_phase.h" + +class b2Contact; +class b2ContactFilter; +class b2ContactListener; +class b2BlockAllocator; + +// Delegate of b2World. +class B2_API 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/b2_distance.h b/src/libraries/box2d/b2_distance.h new file mode 100644 index 000000000..3e05773de --- /dev/null +++ b/src/libraries/box2d/b2_distance.h @@ -0,0 +1,171 @@ +// 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_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 B2_API b2DistanceProxy +{ + b2DistanceProxy() : m_vertices(nullptr), m_count(0), m_radius(0.0f) {} + + /// Initialize the proxy using the given shape. The shape + /// must remain in scope while the proxy is in use. + void Set(const b2Shape* shape, int32 index); + + /// Initialize the proxy using a vertex cloud and radius. The vertices + /// must remain in scope while the proxy is in use. + void Set(const b2Vec2* vertices, int32 count, float radius); + + /// Get the supporting vertex index in the given direction. + int32 GetSupport(const b2Vec2& d) const; + + /// Get the supporting vertex in the given direction. + const b2Vec2& GetSupportVertex(const b2Vec2& d) const; + + /// Get the vertex count. + int32 GetVertexCount() const; + + /// Get a vertex by index. Used by b2Distance. + const b2Vec2& GetVertex(int32 index) const; + + b2Vec2 m_buffer[2]; + const b2Vec2* m_vertices; + int32 m_count; + float m_radius; +}; + +/// Used to warm start b2Distance. +/// Set count to zero on first call. +struct B2_API b2SimplexCache +{ + float metric; ///< length or area + uint16 count; + uint8 indexA[3]; ///< vertices on shape A + uint8 indexB[3]; ///< vertices on shape B +}; + +/// Input for b2Distance. +/// You have to option to use the shape radii +/// in the computation. Even +struct B2_API b2DistanceInput +{ + b2DistanceProxy proxyA; + b2DistanceProxy proxyB; + b2Transform transformA; + b2Transform transformB; + bool useRadii; +}; + +/// Output for b2Distance. +struct B2_API b2DistanceOutput +{ + b2Vec2 pointA; ///< closest point on shapeA + b2Vec2 pointB; ///< closest point on shapeB + float distance; + int32 iterations; ///< number of GJK iterations used +}; + +/// Compute the closest points between two shapes. Supports any combination of: +/// b2CircleShape, b2PolygonShape, b2EdgeShape. The simplex cache is input/output. +/// On the first call set b2SimplexCache.count to zero. +B2_API void b2Distance(b2DistanceOutput* output, + b2SimplexCache* cache, + const b2DistanceInput* input); + +/// Input parameters for b2ShapeCast +struct B2_API b2ShapeCastInput +{ + b2DistanceProxy proxyA; + b2DistanceProxy proxyB; + b2Transform transformA; + b2Transform transformB; + b2Vec2 translationB; +}; + +/// Output results for b2ShapeCast +struct B2_API 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 +B2_API bool b2ShapeCast(b2ShapeCastOutput* output, const b2ShapeCastInput* input); + +////////////////////////////////////////////////////////////////////////// + +inline int32 b2DistanceProxy::GetVertexCount() const +{ + return m_count; +} + +inline const b2Vec2& b2DistanceProxy::GetVertex(int32 index) const +{ + b2Assert(0 <= index && index < m_count); + return m_vertices[index]; +} + +inline int32 b2DistanceProxy::GetSupport(const b2Vec2& d) const +{ + int32 bestIndex = 0; + float bestValue = b2Dot(m_vertices[0], d); + for (int32 i = 1; i < m_count; ++i) + { + float value = b2Dot(m_vertices[i], d); + if (value > bestValue) + { + bestIndex = i; + bestValue = value; + } + } + + return bestIndex; +} + +inline const b2Vec2& b2DistanceProxy::GetSupportVertex(const b2Vec2& d) const +{ + int32 bestIndex = 0; + float bestValue = b2Dot(m_vertices[0], d); + for (int32 i = 1; i < m_count; ++i) + { + float value = b2Dot(m_vertices[i], d); + if (value > bestValue) + { + bestIndex = i; + bestValue = value; + } + } + + return m_vertices[bestIndex]; +} + +#endif diff --git a/src/libraries/box2d/b2_distance_joint.h b/src/libraries/box2d/b2_distance_joint.h new file mode 100644 index 000000000..cfc75fefb --- /dev/null +++ b/src/libraries/box2d/b2_distance_joint.h @@ -0,0 +1,176 @@ +// 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_api.h" +#include "b2_joint.h" + +/// Distance joint definition. This requires defining an anchor point on both +/// 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() + { + type = e_distanceJoint; + 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 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); + + /// The local anchor point relative to bodyA's origin. + b2Vec2 localAnchorA; + + /// The local anchor point relative to bodyB's origin. + b2Vec2 localAnchorB; + + /// The rest length of this joint. Clamped to a stable minimum value. + float length; + + /// 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. + 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 B2_API 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; } + + /// 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; } + + /// 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; + + /// + void Draw(b2Draw* draw) const 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; + 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_lowerImpulse; + float m_upperImpulse; + + // 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_currentLength; + float m_invMassA; + float m_invMassB; + float m_invIA; + float m_invIB; + float m_softMass; + 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..a4d171187 --- /dev/null +++ b/src/libraries/box2d/b2_draw.h @@ -0,0 +1,102 @@ +// 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_api.h" +#include "b2_math.h" + +/// Color for debug drawing. Each value has the range [0,1]. +struct B2_API 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 B2_API 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 77% rename from src/libraries/Box2D/Collision/b2DynamicTree.h rename to src/libraries/box2d/b2_dynamic_tree.h index bf80f73a1..b85491915 100644 --- a/src/libraries/Box2D/Collision/b2DynamicTree.h +++ b/src/libraries/box2d/b2_dynamic_tree.h @@ -1,31 +1,36 @@ -/* -* 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_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 { @@ -48,6 +53,8 @@ struct b2TreeNode // leaf = 0, free node = -1 int32 height; + + bool moved; }; /// A dynamic AABB tree broad-phase, inspired by Nathanael Presson's btDbvt. @@ -58,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. @@ -83,6 +90,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 +123,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(); @@ -147,9 +157,6 @@ private: int32 m_freeList; - /// This is used to incrementally traverse the tree for re-balancing. - uint32 m_path; - int32 m_insertionCount; }; @@ -159,6 +166,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 +235,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 +267,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 +280,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..b930ee872 --- /dev/null +++ b/src/libraries/box2d/b2_edge_shape.h @@ -0,0 +1,86 @@ +// 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_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 B2_API 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 70% rename from src/libraries/Box2D/Dynamics/b2Fixture.h rename to src/libraries/box2d/b2_fixture.h index 753127fbc..f12789b5e 100644 --- a/src/libraries/Box2D/Dynamics/b2Fixture.h +++ b/src/libraries/box2d/b2_fixture.h @@ -1,27 +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_FIXTURE_H #define B2_FIXTURE_H -#include -#include -#include +#include "b2_api.h" +#include "b2_body.h" +#include "b2_collision.h" +#include "b2_shape.h" class b2BlockAllocator; class b2Body; @@ -29,7 +34,7 @@ class b2BroadPhase; class b2Fixture; /// This holds contact filtering data. -struct b2Filter +struct B2_API b2Filter { b2Filter() { @@ -53,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 = NULL; - userData = NULL; + shape = nullptr; friction = 0.2f; restitution = 0.0f; + restitutionThreshold = 1.0f * b2_lengthUnitsPerMeter; density = 0.0f; isSensor = false; } @@ -71,16 +76,20 @@ 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]. - float32 friction; + float friction; /// The restitution (elasticity) usually in the range [0,1]. - float32 restitution; + 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. - float32 density; + float density; /// A sensor shape collects contact information but never generates a collision /// response. @@ -91,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; @@ -104,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. @@ -135,7 +144,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; @@ -147,10 +156,7 @@ public: /// Get the user data that was assigned in the fixture definition. Use this to /// store your application specific data. - void* GetUserData() const; - - /// Set the user data. Use this to store your application specific data. - void SetUserData(void* data); + b2FixtureUserData& GetUserData(); /// Test a point for containment in this fixture. /// @param p a point in world coordinates. @@ -159,6 +165,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 +175,31 @@ 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 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 @@ -215,15 +229,16 @@ 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; + float m_restitutionThreshold; b2FixtureProxy* m_proxies; int32 m_proxyCount; @@ -232,7 +247,7 @@ protected: bool m_isSensor; - void* m_userData; + b2FixtureUserData m_userData; }; inline b2Shape::Type b2Fixture::GetType() const @@ -260,16 +275,11 @@ 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) -{ - m_userData = data; -} - inline b2Body* b2Fixture::GetBody() { return m_body; @@ -290,37 +300,47 @@ 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; } +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 new file mode 100644 index 000000000..99922c3a3 --- /dev/null +++ b/src/libraries/box2d/b2_friction_joint.h @@ -0,0 +1,124 @@ +// 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_api.h" +#include "b2_joint.h" + +/// Friction joint definition. +struct B2_API 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 B2_API 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..1c40687a0 --- /dev/null +++ b/src/libraries/box2d/b2_gear_joint.h @@ -0,0 +1,130 @@ +// 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). +/// @warning bodyB on the input joints must both be dynamic +struct B2_API 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 B2_API 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..ec42e5e9e --- /dev/null +++ b/src/libraries/box2d/b2_growable_stack.h @@ -0,0 +1,91 @@ +// 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 + +#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. +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 62% rename from src/libraries/Box2D/Dynamics/Joints/b2Joint.h rename to src/libraries/box2d/b2_joint.h index dd076b6b2..2b4d586cd 100644 --- a/src/libraries/Box2D/Dynamics/Joints/b2Joint.h +++ b/src/libraries/box2d/b2_joint.h @@ -1,27 +1,33 @@ -/* -* 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_api.h" +#include "b2_math.h" class b2Body; +class b2Draw; class b2Joint; struct b2SolverData; class b2BlockAllocator; @@ -42,19 +48,11 @@ enum b2JointType e_motorJoint }; -enum b2LimitState -{ - e_inactiveLimit, - e_atLowerLimit, - e_atUpperLimit, - e_equalLimits -}; - -struct b2Jacobian +struct B2_API b2Jacobian { b2Vec2 linear; - float32 angularA; - float32 angularB; + float angularA; + float angularB; }; /// A joint edge is used to connect bodies and joints together @@ -62,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 @@ -71,14 +69,13 @@ struct b2JointEdge }; /// Joint definitions are used to construct joints. -struct b2JointDef +struct B2_API b2JointDef { b2JointDef() { type = e_unknownJoint; - userData = NULL; - bodyA = NULL; - bodyB = NULL; + bodyA = nullptr; + bodyB = nullptr; collideConnected = false; } @@ -86,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; @@ -98,9 +95,19 @@ struct b2JointDef bool collideConnected; }; +/// Utility to compute linear stiffness values from frequency and damping ratio +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 +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: @@ -120,23 +127,20 @@ 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(); const b2Joint* GetNext() const; /// Get the user data pointer. - void* GetUserData() const; + b2JointUserData& GetUserData(); - /// 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 +148,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; @@ -180,7 +187,7 @@ protected: bool m_islandFlag; bool m_collideConnected; - void* m_userData; + b2JointUserData m_userData; }; inline b2JointType b2Joint::GetType() const @@ -208,16 +215,11 @@ 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) -{ - m_userData = data; -} - inline bool b2Joint::GetCollideConnected() const { return m_collideConnected; diff --git a/src/libraries/Box2D/Common/b2Math.h b/src/libraries/box2d/b2_math.h similarity index 77% rename from src/libraries/Box2D/Common/b2Math.h rename to src/libraries/box2d/b2_math.h index 755c519b0..cf90ad448 100644 --- a/src/libraries/Box2D/Common/b2Math.h +++ b/src/libraries/box2d/b2_math.h @@ -1,80 +1,69 @@ -/* -* 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 +#include + +#include "b2_api.h" +#include "b2_settings.h" /// 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 std::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() {} /// 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]; } @@ -84,7 +73,7 @@ struct b2Vec2 { x += v.x; y += v.y; } - + /// Subtract a vector from this vector. void operator -= (const b2Vec2& v) { @@ -92,33 +81,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,23 +126,23 @@ struct b2Vec2 return b2Vec2(-y, x); } - float32 x, y; + float x, y; }; /// A 2D column vector with 3 elements. -struct b2Vec3 +struct B2_API b2Vec3 { /// Default constructor does nothing (for performance). 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,16 +160,16 @@ 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. -struct b2Mat22 +struct B2_API b2Mat22 { /// The default constructor does nothing (for performance). b2Mat22() {} @@ -193,7 +182,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 +211,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 +227,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; @@ -254,7 +243,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() {} @@ -296,12 +285,12 @@ struct b2Mat33 }; /// Rotation -struct b2Rot +struct B2_API b2Rot { b2Rot() {} /// Initialize from an angle in radians - explicit b2Rot(float32 angle) + explicit b2Rot(float angle) { /// TODO_ERIN optimize s = sinf(angle); @@ -309,7 +298,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 +313,7 @@ struct b2Rot } /// Get the angle in radians - float32 GetAngle() const + float GetAngle() const { return b2Atan2(s, c); } @@ -342,12 +331,12 @@ struct b2Rot } /// Sine and cosine - float32 s, c; + float s, c; }; /// 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 +352,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); @@ -377,53 +366,54 @@ 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 /// @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; +extern B2_API 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 +444,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 +454,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 +489,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 +571,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 +684,21 @@ inline bool b2IsPowerOfTwo(uint32 x) return result; } -inline void b2Sweep::GetTransform(b2Transform* xf, float32 beta) const +// https://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/ +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; + float angle = (1.0f - beta) * a0 + beta * a; xf->q.Set(angle); // Shift to origin xf->p -= b2Mul(xf->q, localCenter); } -inline void b2Sweep::Advance(float32 alpha) +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 +707,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..c88115f20 --- /dev/null +++ b/src/libraries/box2d/b2_motor_joint.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_MOTOR_JOINT_H +#define B2_MOTOR_JOINT_H + +#include "b2_api.h" +#include "b2_joint.h" + +/// Motor joint definition. +struct B2_API 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 B2_API 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..fcbc56a70 --- /dev/null +++ b/src/libraries/box2d/b2_mouse_joint.h @@ -0,0 +1,134 @@ +// 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_api.h" +#include "b2_joint.h" + +/// Mouse joint definition. This requires a world target point, +/// tuning parameters, and the time step. +struct B2_API 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 B2_API 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/b2_polygon_shape.h b/src/libraries/box2d/b2_polygon_shape.h new file mode 100644 index 000000000..5a4e563f8 --- /dev/null +++ b/src/libraries/box2d/b2_polygon_shape.h @@ -0,0 +1,95 @@ +// 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 "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 B2_API b2PolygonShape : public b2Shape +{ +public: + b2PolygonShape(); + + /// Implement b2Shape. + b2Shape* Clone(b2BlockAllocator* allocator) const override; + + /// @see b2Shape::GetChildCount + int32 GetChildCount() const override; + + /// Create a convex hull from the given array of local points. + /// The count must be in the range [3, b2_maxPolygonVertices]. + /// @warning the points may be re-ordered, even if they form a convex polygon + /// @warning collinear points are handled but not removed. Collinear points + /// may lead to poor stacking behavior. + void Set(const b2Vec2* points, int32 count); + + /// Build vertices to represent an axis-aligned box centered on the local origin. + /// @param hx the half-width. + /// @param hy the half-height. + void SetAsBox(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(float hx, float hy, const b2Vec2& center, float angle); + + /// @see b2Shape::TestPoint + 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 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; + + /// Validate convexity. This is a very time consuming operation. + /// @returns true if valid + bool Validate() const; + + b2Vec2 m_centroid; + b2Vec2 m_vertices[b2_maxPolygonVertices]; + b2Vec2 m_normals[b2_maxPolygonVertices]; + int32 m_count; +}; + +inline b2PolygonShape::b2PolygonShape() +{ + m_type = e_polygon; + m_radius = b2_polygonRadius; + m_count = 0; + m_centroid.SetZero(); +} + +#endif diff --git a/src/libraries/Box2D/Dynamics/Joints/b2PrismaticJoint.h b/src/libraries/box2d/b2_prismatic_joint.h similarity index 56% rename from src/libraries/Box2D/Dynamics/Joints/b2PrismaticJoint.h rename to src/libraries/box2d/b2_prismatic_joint.h index 6ef5d3ec0..9d12d2126 100644 --- a/src/libraries/Box2D/Dynamics/Joints/b2PrismaticJoint.h +++ b/src/libraries/box2d/b2_prismatic_joint.h @@ -1,25 +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_PRISMATIC_JOINT_H #define B2_PRISMATIC_JOINT_H -#include +#include "b2_api.h" +#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 @@ -27,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() { @@ -58,39 +63,39 @@ 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 /// 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; - 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 +107,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 +122,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 +137,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 54% rename from src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.h rename to src/libraries/box2d/b2_pulley_joint.h index 44843e7b4..6b1445641 100644 --- a/src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.h +++ b/src/libraries/box2d/b2_pulley_joint.h @@ -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 + +// 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_api.h" +#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. -struct b2PulleyJointDef : public b2JointDef +struct B2_API b2PulleyJointDef : public b2JointDef { b2PulleyJointDef() { @@ -44,7 +49,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 +64,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. @@ -76,14 +81,14 @@ 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; - 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 +97,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 +147,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 53% rename from src/libraries/Box2D/Dynamics/Joints/b2RevoluteJoint.h rename to src/libraries/box2d/b2_revolute_joint.h index bbed4a6cb..36ad5314e 100644 --- a/src/libraries/Box2D/Dynamics/Joints/b2RevoluteJoint.h +++ b/src/libraries/box2d/b2_revolute_joint.h @@ -1,38 +1,42 @@ -/* -* 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_api.h" +#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. /// 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() { @@ -59,26 +63,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 @@ -87,11 +91,11 @@ 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; - 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 +104,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 +119,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,55 +134,58 @@ 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: - + friend class b2Joint; friend class b2GearJoint; 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 +194,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..47f5fc442 --- /dev/null +++ b/src/libraries/box2d/b2_rope.h @@ -0,0 +1,153 @@ +// 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_api.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, + b2_pbdTriangleBendingModel +}; + +/// +struct B2_API 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 B2_API 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 B2_API 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 SolveBend_PBD_Triangle(); + 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_settings.h b/src/libraries/box2d/b2_settings.h new file mode 100644 index 000000000..48cd95dfe --- /dev/null +++ b/src/libraries/box2d/b2_settings.h @@ -0,0 +1,127 @@ +// 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 + +#include "b2_types.h" +#include "b2_api.h" + +/// @file +/// Settings that can be overriden for your application +/// + +/// Define this macro in your build if you want to override settings +#ifdef B2_USER_SETTINGS + +/// 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 + +// User data + +/// You can define this to inject whatever data you want in b2Body +struct B2_API b2BodyUserData +{ + b2BodyUserData() + { + pointer = 0; + } + + /// For legacy compatibility + uintptr_t pointer; +}; + +/// You can define this to inject whatever data you want in b2Fixture +struct B2_API b2FixtureUserData +{ + b2FixtureUserData() + { + pointer = 0; + } + + /// For legacy compatibility + uintptr_t pointer; +}; + +/// You can define this to inject whatever data you want in b2Joint +struct B2_API b2JointUserData +{ + b2JointUserData() + { + pointer = 0; + } + + /// 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. +inline void* b2Alloc(int32 size) +{ + return b2Alloc_Default(size); +} + +/// If you implement b2Alloc, you should also implement this function. +inline void b2Free(void* mem) +{ + b2Free_Default(mem); +} + +/// 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 + +#include "b2_common.h" + +#endif diff --git a/src/libraries/Box2D/Collision/Shapes/b2Shape.h b/src/libraries/box2d/b2_shape.h similarity index 60% rename from src/libraries/Box2D/Collision/Shapes/b2Shape.h rename to src/libraries/box2d/b2_shape.h index 170ea1a13..cbed2b863 100644 --- a/src/libraries/Box2D/Collision/Shapes/b2Shape.h +++ b/src/libraries/box2d/b2_shape.h @@ -1,48 +1,54 @@ -/* -* 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_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. - 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. /// 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, @@ -87,10 +93,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..1db2af5d9 --- /dev/null +++ b/src/libraries/box2d/b2_stack_allocator.h @@ -0,0 +1,65 @@ +// 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_api.h" +#include "b2_settings.h" + +const int32 b2_stackSize = 100 * 1024; // 100k +const int32 b2_maxStackEntries = 32; + +struct B2_API 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 B2_API 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..04d46262e --- /dev/null +++ b/src/libraries/box2d/b2_time_of_impact.h @@ -0,0 +1,63 @@ +// 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_api.h" +#include "b2_math.h" +#include "b2_distance.h" + +/// Input parameters for b2TimeOfImpact +struct B2_API b2TOIInput +{ + b2DistanceProxy proxyA; + b2DistanceProxy proxyB; + b2Sweep sweepA; + b2Sweep sweepB; + float tMax; // defines sweep interval [0, tMax] +}; + +/// Output parameters for b2TimeOfImpact. +struct B2_API 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. +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 new file mode 100644 index 000000000..13d6292ec --- /dev/null +++ b/src/libraries/box2d/b2_time_step.h @@ -0,0 +1,74 @@ +// 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_api.h" +#include "b2_math.h" + +/// Profiling data. Times are in milliseconds. +struct B2_API b2Profile +{ + float step; + float collide; + float solve; + float solveInit; + float solveVelocity; + float solvePosition; + float broadphase; + float solveTOI; +}; + +/// This is an internal structure. +struct B2_API 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 B2_API b2Position +{ + b2Vec2 c; + float a; +}; + +/// This is an internal structure. +struct B2_API b2Velocity +{ + b2Vec2 v; + float w; +}; + +/// Solver Data +struct B2_API 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..7893c3270 --- /dev/null +++ b/src/libraries/box2d/b2_timer.h @@ -0,0 +1,55 @@ +// 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_api.h" +#include "b2_settings.h" + +/// Timer for profiling. This has platform specific code and may +/// not work on every platform. +class B2_API 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_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 new file mode 100644 index 000000000..f226c8a46 --- /dev/null +++ b/src/libraries/box2d/b2_weld_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_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 B2_API 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 B2_API 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..8576adbd2 --- /dev/null +++ b/src/libraries/box2d/b2_wheel_joint.h @@ -0,0 +1,240 @@ +// 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_api.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 B2_API 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 B2_API 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 81% rename from src/libraries/Box2D/Dynamics/b2World.h rename to src/libraries/box2d/b2_world.h index 3968cc784..57d37096c 100644 --- a/src/libraries/Box2D/Dynamics/b2World.h +++ b/src/libraries/box2d/b2_world.h @@ -1,30 +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_WORLD_H #define B2_WORLD_H -#include -#include -#include -#include -#include -#include +#include "b2_api.h" +#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; @@ -38,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. @@ -54,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 @@ -62,7 +67,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 +96,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 +110,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 +127,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,11 +182,11 @@ 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); - + /// Get the global gravity vector. b2Vec2 GetGravity() const; @@ -211,14 +216,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 +224,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 +241,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 +318,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 73% rename from src/libraries/Box2D/Dynamics/b2WorldCallbacks.h rename to src/libraries/box2d/b2_world_callbacks.h index 82ffc0229..da45640e2 100644 --- a/src/libraries/Box2D/Dynamics/b2WorldCallbacks.h +++ b/src/libraries/box2d/b2_world_callbacks.h @@ -1,25 +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_WORLD_CALLBACKS_H #define B2_WORLD_CALLBACKS_H -#include +#include "b2_api.h" +#include "b2_settings.h" struct b2Vec2; struct b2Transform; @@ -33,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() {} @@ -49,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() {} @@ -62,10 +67,10 @@ 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 { - float32 normalImpulses[b2_maxManifoldPoints]; - float32 tangentImpulses[b2_maxManifoldPoints]; + float normalImpulses[b2_maxManifoldPoints]; + float tangentImpulses[b2_maxManifoldPoints]; int32 count; }; @@ -78,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() {} @@ -120,7 +125,7 @@ public: /// Callback class for AABB queries. /// See b2World::Query -class b2QueryCallback +class B2_API b2QueryCallback { public: virtual ~b2QueryCallback() {} @@ -132,7 +137,7 @@ public: /// Callback class for ray casts. /// See b2World::RayCast -class b2RayCastCallback +class B2_API b2RayCastCallback { public: virtual ~b2RayCastCallback() {} @@ -146,10 +151,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/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..244132408 100644 --- a/src/libraries/Box2D/Collision/b2Distance.cpp +++ b/src/libraries/box2d/collision/b2_distance.cpp @@ -1,29 +1,33 @@ -/* -* 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; +B2_API int32 b2_gjkCalls, b2_gjkIters, b2_gjkMaxIters; void b2DistanceProxy::Set(const b2Shape* shape, int32 index) { @@ -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..55a9d3246 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() @@ -38,8 +41,6 @@ b2DynamicTree::b2DynamicTree() m_nodes[m_nodeCapacity-1].height = -1; m_freeList = 0; - m_path = 0; - m_insertionCount = 0; } @@ -83,7 +84,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 +114,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 +136,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 +213,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 +237,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 +254,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 +282,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 +549,7 @@ int32 b2DynamicTree::GetHeight() const } // -float32 b2DynamicTree::GetAreaRatio() const +float b2DynamicTree::GetAreaRatio() const { if (m_root == b2_nullNode) { @@ -536,9 +557,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 +673,7 @@ void b2DynamicTree::ValidateMetrics(int32 index) const void b2DynamicTree::Validate() const { +#if defined(b2DEBUG) ValidateStructure(m_root); ValidateMetrics(m_root); @@ -667,6 +689,7 @@ void b2DynamicTree::Validate() const b2Assert(GetHeight() == ComputeHeight()); b2Assert(m_nodeCount + freeCount == m_nodeCapacity); +#endif } int32 b2DynamicTree::GetMaxBalance() const @@ -719,7 +742,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 +753,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 77% rename from src/libraries/Box2D/Collision/b2TimeOfImpact.cpp rename to src/libraries/box2d/collision/b2_time_of_impact.cpp index 60da95c38..7a1011b7e 100644 --- a/src/libraries/Box2D/Collision/b2TimeOfImpact.cpp +++ b/src/libraries/box2d/collision/b2_time_of_impact.cpp @@ -1,33 +1,37 @@ -/* -* 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; -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 @@ -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.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..5ee213ef2 --- /dev/null +++ b/src/libraries/box2d/common/b2_settings.cpp @@ -0,0 +1,82 @@ +// 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 + +#include "common/Exception.h" + +b2Version b2_version = {2, 4, 0}; + +// Memory allocators. Modify these to use your own allocator. +void* b2Alloc_Default(int32 size) +{ + return malloc(size); +} + +void b2Free_Default(void* mem) +{ + free(mem); +} + +// You can modify this to use your logging facility. +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) +{ + 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/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..574666442 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) @@ -436,33 +434,47 @@ void b2Body::SetTransform(const b2Vec2& position, float32 angle) { f->Synchronize(broadPhase, m_xf, m_xf); } + + // Check for new contacts the next step + m_world->m_newContacts = true; } 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 +483,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 +505,7 @@ void b2Body::SetActive(bool flag) ce = ce->next; m_world->m_contactManager.Destroy(ce0->contact); } - m_contactList = NULL; + m_contactList = nullptr; } } @@ -522,28 +535,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 71% rename from src/libraries/Box2D/Dynamics/Contacts/b2Contact.cpp rename to src/libraries/box2d/dynamics/b2_contact.cpp index d9f1021e4..1c65bc895 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,23 +139,24 @@ 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; 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/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 78% rename from src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.cpp rename to src/libraries/box2d/dynamics/b2_contact_solver.cpp index e31b6c236..e6f432a23 100644 --- a/src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.cpp +++ b/src/libraries/box2d/dynamics/b2_contact_solver.cpp @@ -1,32 +1,37 @@ -/* -* 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; +B2_API bool g_blockSolve = true; struct b2ContactPositionConstraint { @@ -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(); @@ -75,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; @@ -144,29 +150,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,26 +195,26 @@ 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)); - if (vRel < -b2_velocityThreshold) + float vRel = b2Dot(vc->normal, vB + b2Cross(wB, vcp->rB) - vA - b2Cross(wA, vcp->rA)); + if (vRel < -vc->threshold) { vcp->velocityBias = -vc->restitution * vRel; } @@ -220,17 +226,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 +263,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 +302,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 +329,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 +351,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 +381,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 +422,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 +432,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 +491,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 +669,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 +684,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 +711,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 +720,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 +754,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 +766,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 +783,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 +802,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 +811,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..1064738ef --- /dev/null +++ b/src/libraries/box2d/dynamics/b2_contact_solver.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_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 threshold; + 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/b2_distance_joint.cpp b/src/libraries/box2d/dynamics/b2_distance_joint.cpp new file mode 100644 index 000000000..e54dbaf4f --- /dev/null +++ b/src/libraries/box2d/dynamics/b2_distance_joint.cpp @@ -0,0 +1,421 @@ +// 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_distance_joint.h" +#include "box2d/b2_time_step.h" + +// 1-D constrained system +// m (v2 - v1) = lambda +// v2 + (beta/h) * x1 + gamma * lambda = 0, gamma has units of inverse mass. +// x2 = x1 + h * v2 + +// 1-D mass-damper-spring system +// m (v2 - v1) + h * d * v2 + h * k * + +// C = norm(p2 - p1) - L +// u = (p2 - p1) / norm(p2 - p1) +// Cdot = dot(u, v2 + cross(w2, r2) - v1 - cross(w1, r1)) +// J = [-u -cross(r1, u) u cross(r2, u)] +// K = J * invM * JT +// = invMass1 + invI1 * cross(r1, u)^2 + invMass2 + invI2 * cross(r2, u)^2 + + +void b2DistanceJointDef::Initialize(b2Body* b1, b2Body* b2, + const b2Vec2& anchor1, const b2Vec2& anchor2) +{ + bodyA = b1; + bodyB = b2; + localAnchorA = bodyA->GetLocalPoint(anchor1); + localAnchorB = bodyB->GetLocalPoint(anchor2); + b2Vec2 d = anchor2 - anchor1; + length = b2Max(d.Length(), b2_linearSlop); + minLength = length; + maxLength = length; +} + +b2DistanceJoint::b2DistanceJoint(const b2DistanceJointDef* def) +: b2Joint(def) +{ + m_localAnchorA = def->localAnchorA; + m_localAnchorB = def->localAnchorB; + 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_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) +{ + 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; + + // Handle singularity. + m_currentLength = m_u.Length(); + if (m_currentLength > b2_linearSlop) + { + 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 && m_minLength < m_maxLength) + { + // soft + float C = m_currentLength - m_length; + + float d = m_damping; + float k = m_stiffness; + + // 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 + 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_softMass = invMass != 0.0f ? 1.0f / invMass : 0.0f; + } + else + { + // rigid + m_gamma = 0.0f; + m_bias = 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_lowerImpulse - m_upperImpulse) * m_u; + vA -= m_invMassA * P; + wA -= m_invIA * b2Cross(m_rA, P); + vB += m_invMassB * P; + wB += m_invIB * b2Cross(m_rB, P); + } + else + { + m_impulse = 0.0f; + } + + data.velocities[m_indexA].v = vA; + data.velocities[m_indexA].w = wA; + data.velocities[m_indexB].v = vB; + data.velocities[m_indexB].w = wB; +} + +void b2DistanceJoint::SolveVelocityConstraints(const b2SolverData& data) +{ + b2Vec2 vA = data.velocities[m_indexA].v; + float wA = data.velocities[m_indexA].w; + b2Vec2 vB = data.velocities[m_indexB].v; + float wB = data.velocities[m_indexB].w; + + 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_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); + } + + // 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; + data.velocities[m_indexB].v = vB; + data.velocities[m_indexB].w = wB; +} + +bool b2DistanceJoint::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; + + float length = u.Normalize(); + 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; + + cA -= m_invMassA * P; + aA -= m_invIA * b2Cross(rA, P); + cB += m_invMassB * P; + aB += m_invIB * b2Cross(rB, P); + + data.positions[m_indexA].c = cA; + data.positions[m_indexA].a = aA; + data.positions[m_indexB].c = cB; + data.positions[m_indexB].a = aB; + + return b2Abs(C) < b2_linearSlop; +} + +b2Vec2 b2DistanceJoint::GetAnchorA() const +{ + return m_bodyA->GetWorldPoint(m_localAnchorA); +} + +b2Vec2 b2DistanceJoint::GetAnchorB() const +{ + return m_bodyB->GetWorldPoint(m_localAnchorB); +} + +b2Vec2 b2DistanceJoint::GetReactionForce(float inv_dt) const +{ + b2Vec2 F = inv_dt * (m_impulse + m_lowerImpulse - m_upperImpulse) * m_u; + return F; +} + +float b2DistanceJoint::GetReactionTorque(float inv_dt) const +{ + B2_NOT_USED(inv_dt); + 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; + int32 indexB = m_bodyB->m_islandIndex; + + 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.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_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..9fd700aa9 100644 --- a/src/libraries/Box2D/Dynamics/b2Fixture.cpp +++ b/src/libraries/box2d/dynamics/b2_fixture.cpp @@ -1,40 +1,43 @@ -/* -* 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_body = nullptr; + m_next = nullptr; + m_proxies = nullptr; m_proxyCount = 0; - m_shape = NULL; + m_shape = nullptr; m_density = 0.0f; } @@ -43,9 +46,10 @@ 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 = 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,65 @@ 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.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); + 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 +298,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 73% rename from src/libraries/Box2D/Dynamics/Joints/b2GearJoint.cpp rename to src/libraries/box2d/dynamics/b2_gear_joint.cpp index 155eb0c1d..ff36d3e10 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,18 +57,21 @@ 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. 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; - 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) { @@ -92,11 +99,14 @@ 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; - 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 +157,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 +245,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 +281,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 +347,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 +387,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 +418,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..bd42b5446 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 "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..41addbbb2 --- /dev/null +++ b/src/libraries/box2d/dynamics/b2_joint.cpp @@ -0,0 +1,301 @@ +// 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_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_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_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..00e77690e --- /dev/null +++ b/src/libraries/box2d/dynamics/b2_prismatic_joint.cpp @@ -0,0 +1,643 @@ +// 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..f7cc4cc29 --- /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_motorImpulse + 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/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..c23b98460 --- /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_lowerImpulse - m_upperImpulse) * 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/b2_rope.cpp b/src/libraries/box2d/rope/b2_rope.cpp new file mode 100644 index 000000000..d2425a2af --- /dev/null +++ b/src/libraries/box2d/rope/b2_rope.cpp @@ -0,0 +1,809 @@ +// 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(); + } + else if (m_tuning.bendingModel == b2_pbdTriangleBendingModel) + { + SolveBend_PBD_Triangle(); + } + + 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; + } +} + +// 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); + 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/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 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 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; 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/GlslangToSpv.cpp b/src/libraries/glslang/SPIRV/GlslangToSpv.cpp index 3e420aa26..b86793e1e 100644 --- a/src/libraries/glslang/SPIRV/GlslangToSpv.cpp +++ b/src/libraries/glslang/SPIRV/GlslangToSpv.cpp @@ -56,7 +56,9 @@ namespace spv { #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 @@ -281,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) { @@ -1440,7 +1444,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, // Add the source extensions const auto& sourceExtensions = glslangIntermediate->getRequestedExtensions(); for (auto it = sourceExtensions.begin(); it != sourceExtensions.end(); ++it) - builder.addSourceExtension(it->first.c_str()); + builder.addSourceExtension(it->c_str()); // Add the top-level modes for this shader. @@ -1711,16 +1715,19 @@ 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); + } } } @@ -2051,9 +2058,9 @@ std::pair TGlslangToSpvTraverser::getForcedType(glslang::TBuil // builtins. During visitBinary we insert a transpose case glslang::EbvWorldToObject3x4: case glslang::EbvObjectToWorld3x4: { - std::pair ret(builder.makeMatrixType(builder.makeFloatType(32), 4, 3), - builder.makeMatrixType(builder.makeFloatType(32), 3, 4) - ); + 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: @@ -2978,7 +2985,8 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt // receive the result, and must later swizzle that into the original // l-value. complexLvalues.push_back(builder.getAccessChain()); - temporaryLvalues.push_back(builder.createVariable(spv::StorageClassFunction, + temporaryLvalues.push_back(builder.createVariable( + spv::NoPrecision, spv::StorageClassFunction, builder.accessChainGetInferredType(), "swizzleTemp")); operands.push_back(temporaryLvalues.back()); } else { @@ -3081,7 +3089,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt for (unsigned int i = 0; i < temporaryLvalues.size(); ++i) { builder.setAccessChain(complexLvalues[i]); - builder.accessChainStore(builder.createLoad(temporaryLvalues[i])); + builder.accessChainStore(builder.createLoad(temporaryLvalues[i], spv::NoPrecision)); } } @@ -3198,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); @@ -3223,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); @@ -3421,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 @@ -3536,7 +3549,7 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol* false /* specConst */); } - return builder.createVariable(storageClass, spvType, name, initializer); + return builder.createVariable(spv::NoPrecision, storageClass, spvType, name, initializer); } // Return type Id of the sampled type. @@ -4727,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]; @@ -5331,7 +5344,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg ++lValueCount; } else if (writableParam(qualifiers[a])) { // need space to hold the copy - arg = builder.createVariable(spv::StorageClassFunction, + 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 @@ -5344,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; @@ -5368,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); } @@ -5613,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 @@ -6311,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); @@ -6460,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); @@ -6669,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; @@ -8651,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 @@ -8671,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; @@ -8697,6 +8723,7 @@ void OutputSpvHex(const std::vector& spirv, const char* baseName, } if (varName != nullptr) { out << "};"; + out << std::endl; } out.close(); #endif @@ -8734,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/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 6cf70a12d..968033146 100644 --- a/src/libraries/glslang/SPIRV/SpvBuilder.cpp +++ b/src/libraries/glslang/SPIRV/SpvBuilder.cpp @@ -1183,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); @@ -1221,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); @@ -1229,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) @@ -1242,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) @@ -1271,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) { @@ -1297,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 @@ -1356,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); @@ -1378,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(); } @@ -1434,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); @@ -1452,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(); } @@ -2166,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: @@ -2674,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); } @@ -2713,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); } @@ -2732,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 { @@ -2753,8 +2855,7 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu // loaded image types get decorated. TODO: This should maybe move to // createImageTextureFunctionCall. addDecoration(id, nonUniform); - id = createLoad(id, memoryAccess, scope, alignment); - setPrecision(id, precision); + id = createLoad(id, precision, memoryAccess, scope, alignment); addDecoration(id, nonUniform); } diff --git a/src/libraries/glslang/SPIRV/SpvBuilder.h b/src/libraries/glslang/SPIRV/SpvBuilder.h index 71b90d609..077945e77 100644 --- a/src/libraries/glslang/SPIRV/SpvBuilder.h +++ b/src/libraries/glslang/SPIRV/SpvBuilder.h @@ -248,6 +248,13 @@ public: { 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); @@ -314,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; } @@ -347,7 +361,8 @@ 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); @@ -357,7 +372,8 @@ public: 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, + 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 diff --git a/src/libraries/glslang/SPIRV/SpvTools.cpp b/src/libraries/glslang/SPIRV/SpvTools.cpp index 1e968ba54..112ac33c5 100644 --- a/src/libraries/glslang/SPIRV/SpvTools.cpp +++ b/src/libraries/glslang/SPIRV/SpvTools.cpp @@ -80,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) @@ -128,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& intermediate, std::vector& spirv, - spv::SpvBuildLogger* logger, 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 @@ -175,6 +177,9 @@ void SpirvToolsLegalize(const glslang::TIntermediate& intermediate, 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()); @@ -212,6 +217,25 @@ void SpirvToolsLegalize(const glslang::TIntermediate& intermediate, std::vector< 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); +} + }; // end namespace glslang #endif 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 4faa89ea3..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" { @@ -519,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 b1f2b820d..1d052f8c2 100644 --- a/src/libraries/glslang/SPIRV/doc.cpp +++ b/src/libraries/glslang/SPIRV/doc.cpp @@ -134,7 +134,7 @@ const char* MemoryString(int mem) } } -const int ExecutionModeCeiling = 33; +const int ExecutionModeCeiling = 40; const char* ExecutionModeString(int mode) { @@ -173,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"; @@ -188,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"; } @@ -938,6 +957,9 @@ const char* CapabilityString(int info) case CapabilityIntegerFunctions2INTEL: return "CapabilityIntegerFunctions2INTEL"; + case CapabilityAtomicFloat32AddEXT: return "AtomicFloat32AddEXT"; + case CapabilityAtomicFloat64AddEXT: return "AtomicFloat64AddEXT"; + default: return "Bad"; } } @@ -1269,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"; @@ -1313,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"; @@ -1418,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); @@ -1604,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'"); @@ -1697,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'"); @@ -1707,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'"); @@ -2260,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'"); 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/spirv.hpp b/src/libraries/glslang/SPIRV/spirv.hpp index dae36cf20..35482ea5e 100644 --- a/src/libraries/glslang/SPIRV/spirv.hpp +++ b/src/libraries/glslang/SPIRV/spirv.hpp @@ -168,6 +168,10 @@ enum ExecutionMode { ExecutionModeSampleInterlockUnorderedEXT = 5369, ExecutionModeShadingRateInterlockOrderedEXT = 5370, ExecutionModeShadingRateInterlockUnorderedEXT = 5371, + ExecutionModeMaxWorkgroupSizeINTEL = 5893, + ExecutionModeMaxWorkDimINTEL = 5894, + ExecutionModeNoGlobalOffsetINTEL = 5895, + ExecutionModeNumSIMDWorkitemsINTEL = 5896, ExecutionModeMax = 0x7fffffff, }; @@ -199,6 +203,7 @@ enum StorageClass { StorageClassShaderRecordBufferNV = 5343, StorageClassPhysicalStorageBuffer = 5349, StorageClassPhysicalStorageBufferEXT = 5349, + StorageClassCodeSectionINTEL = 5605, StorageClassMax = 0x7fffffff, }; @@ -477,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, }; @@ -628,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, }; @@ -642,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 { @@ -928,9 +960,20 @@ 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, }; @@ -1398,6 +1441,8 @@ enum Op { OpUSubSatINTEL = 5596, OpIMul32x16INTEL = 5597, OpUMul32x16INTEL = 5598, + OpFunctionPointerINTEL = 5600, + OpFunctionPointerCallINTEL = 5601, OpDecorateString = 5632, OpDecorateStringGOOGLE = 5632, OpMemberDecorateString = 5633, @@ -1520,6 +1565,10 @@ enum Op { OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + OpLoopControlINTEL = 5887, + OpReadPipeBlockingINTEL = 5946, + OpWritePipeBlockingINTEL = 5947, + OpFPGARegINTEL = 5949, OpRayQueryGetRayTMinKHR = 6016, OpRayQueryGetRayFlagsKHR = 6017, OpRayQueryGetIntersectionTKHR = 6018, @@ -1537,6 +1586,7 @@ enum Op { OpRayQueryGetWorldRayOriginKHR = 6030, OpRayQueryGetIntersectionObjectToWorldKHR = 6031, OpRayQueryGetIntersectionWorldToObjectKHR = 6032, + OpAtomicFAddEXT = 6035, OpMax = 0x7fffffff, }; @@ -1955,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; @@ -2075,6 +2127,10 @@ 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; @@ -2092,6 +2148,7 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { 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 */ diff --git a/src/libraries/glslang/SPIRV/spvIR.h b/src/libraries/glslang/SPIRV/spvIR.h old mode 100755 new mode 100644 index 6523035e7..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 { @@ -351,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 @@ -379,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 }; // @@ -439,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/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/intermediate.h b/src/libraries/glslang/glslang/Include/intermediate.h index bf12fcf8f..30cb6fb17 100644 --- a/src/libraries/glslang/glslang/Include/intermediate.h +++ b/src/libraries/glslang/glslang/Include/intermediate.h @@ -1231,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/Initialize.cpp b/src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp index 4806f7381..3fd6ab21f 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp @@ -147,6 +147,10 @@ EProfile EDesktopProfile = static_cast(ENoProfile | ECoreProfile | ECo #ifdef GLSLANG_WEB const Versioning* Es300Desktop130 = 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 }, @@ -415,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 @@ -499,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"; @@ -516,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 @@ -541,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); @@ -586,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);" @@ -1173,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)) { @@ -1210,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);" @@ -1241,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);" @@ -1254,12 +1274,17 @@ 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 >= 150)) { // GL_ARB_shader_bit_encoding @@ -1299,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);" @@ -1307,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)) { @@ -1324,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);" @@ -1341,6 +1369,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } +#endif #endif if ((profile == EEsProfile && version >= 300) || @@ -1450,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.) @@ -1604,6 +1634,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } } +#endif // !GLSLANG_ANGLE // Bitfield if ((profile == EEsProfile && version >= 310) || @@ -1746,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( @@ -3066,6 +3098,7 @@ 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 @@ -3085,6 +3118,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } +#ifndef GLSLANG_ANGLE // GL_AMD_gpu_shader_half_float/Explicit types if (profile != EEsProfile && version >= 450) { commonBuiltins.append( @@ -3935,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 //============================================================================ // @@ -3972,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. // @@ -4037,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)) { @@ -4057,7 +4095,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "void EndPrimitive();" "\n"); } -#endif +#endif // !GLSLANG_WEB //============================================================================ // @@ -4117,6 +4155,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV 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 @@ -4243,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) { @@ -4280,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( @@ -4414,12 +4455,14 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "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); @@ -4432,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 //============================================================================ // @@ -4469,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. @@ -4587,7 +4631,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#endif +#endif // !GLSLANG_WEB && !GLSLANG_ANGLE //============================================================================ // @@ -4618,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. @@ -4705,6 +4750,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } } +#endif // !GLSLANG_ANGLE //============================================================================ // @@ -5375,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 = @@ -5405,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)) { @@ -5616,6 +5663,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV stageBuiltins[EShLangCallable].append(callableDecls); } + if ((profile != EEsProfile && version >= 140)) { const char *deviceIndex = "in highp int gl_DeviceIndex;" // GL_EXT_device_group @@ -5628,12 +5676,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV stageBuiltins[EShLangMiss].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"); - } - if ((profile != EEsProfile && version >= 420) || (profile == EEsProfile && version >= 310)) { commonBuiltins.append("const int gl_ScopeDevice = 1;\n"); @@ -5657,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()); @@ -5675,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 @@ -5706,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)) @@ -6028,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"); + } } } @@ -6101,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 // @@ -6177,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) @@ -6190,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) @@ -6202,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) @@ -6257,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("("); @@ -6357,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 @@ -6386,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) { @@ -6629,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 // @@ -7057,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)) { @@ -7093,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) { @@ -7109,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); @@ -7131,6 +7227,7 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf s.append("\n"); } +#endif #endif s.append("\n"); @@ -7215,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 // @@ -7404,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); @@ -7565,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: @@ -8092,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: @@ -8224,10 +8324,10 @@ 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 +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) case EShLangRayGen: case EShLangIntersect: case EShLangAnyHit: @@ -9139,7 +9239,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion default: assert(false && "Language not supported"); } -#endif +#endif // !GLSLANG_WEB } // @@ -9154,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); 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 52ec6115f..b8c220d78 --- a/src/libraries/glslang/glslang/MachineIndependent/Intermediate.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/Intermediate.cpp @@ -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); @@ -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; } @@ -1659,64 +1655,45 @@ 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; + } } - } else if (isEsProfile()) { + } + + if (isEsProfile()) { switch (to) { case EbtFloat: switch (from) { case EbtInt: case EbtUint: - return extensionRequested(E_GL_EXT_shader_implicit_conversions); - case EbtFloat: - return true; + return numericFeatures.contains(TNumericFeatures::shader_implicit_conversions); default: return false; } case EbtUint: switch (from) { case EbtInt: - return extensionRequested(E_GL_EXT_shader_implicit_conversions); - case EbtUint: - return true; + return numericFeatures.contains(TNumericFeatures::shader_implicit_conversions); default: return false; } @@ -1732,15 +1709,14 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat case EbtInt64: case EbtUint64: case EbtFloat: - case EbtDouble: - return version >= 400 || extensionRequested(E_GL_ARB_gpu_shader_fp64); + return version >= 400 || numericFeatures.contains(TNumericFeatures::gpu_shader_fp64); case EbtInt16: case EbtUint16: - return (version >= 400 || extensionRequested(E_GL_ARB_gpu_shader_fp64)) && - 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 (version >= 400 || extensionRequested(E_GL_ARB_gpu_shader_fp64)) && - 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; } @@ -1748,16 +1724,15 @@ 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) || getSource() == EShSourceHlsl; + return numericFeatures.contains(TNumericFeatures::gpu_shader_half_float) || + getSource() == EShSourceHlsl; default: return false; } @@ -1765,24 +1740,20 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat switch (from) { case EbtInt: return version >= 400 || getSource() == EShSourceHlsl; - case EbtUint: - 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); 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; } @@ -1791,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; } @@ -1813,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; } @@ -1823,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; } @@ -1951,13 +1917,13 @@ 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 < 310 || !extensionRequested(E_GL_EXT_shader_implicit_conversions))) || + (version < 310 || !numericFeatures.contains(TNumericFeatures::shader_implicit_conversions))) || version == 110) return std::make_tuple(res0, res1); @@ -2490,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); @@ -2777,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. @@ -3284,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; } @@ -3782,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); @@ -3793,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/ParseHelper.cpp b/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp index a35d41a05..86a5a3786 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp @@ -246,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; } @@ -270,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; } @@ -751,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()); @@ -1295,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) { @@ -1415,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. @@ -1675,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(); @@ -2105,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(), ""); @@ -2134,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; } @@ -2767,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 || @@ -2775,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); @@ -5776,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 @@ -6528,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(); @@ -7283,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 { @@ -7461,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"); } } diff --git a/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h b/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h index 8b262c946..0f09adaff 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h +++ b/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h @@ -84,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), @@ -328,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&); diff --git a/src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp b/src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp index a1392dbde..4091320cd 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp @@ -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,6 +367,7 @@ 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, EShLangRayGen, source, @@ -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: @@ -867,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 (" @@ -890,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) @@ -963,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(); @@ -1000,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 @@ -1223,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 @@ -1684,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() @@ -1860,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. // @@ -1898,7 +1924,7 @@ const char* TShader::getInfoDebugLog() } TProgram::TProgram() : -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) reflection(0), #endif linked(false) @@ -1914,7 +1940,7 @@ TProgram::TProgram() : TProgram::~TProgram() { delete infoSink; -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) delete reflection; #endif @@ -1961,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) { @@ -2015,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; } @@ -2031,7 +2059,7 @@ const char* TProgram::getInfoDebugLog() return infoSink->debug.c_str(); } -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) // // Reflection implementation. @@ -2113,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 06b5a813d..007f22c1b 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.cpp @@ -178,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 4e755f475..569e5391d 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/Versions.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/Versions.cpp @@ -167,7 +167,7 @@ void TParseVersions::initializeExtensionBehavior() const extensionData exts[] = { {E_GL_EXT_ray_tracing, EShTargetSpv_1_4} }; - for (int ii = 0; ii < sizeof(exts) / sizeof(exts[0]); ii++) { + 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; @@ -348,6 +348,7 @@ 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 @@ -476,11 +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 E_GL_EXT_ray_tracing 1\n" - "#define E_GL_EXT_ray_query 1\n" - "#define E_GL_EXT_ray_flags_primitive_culling 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" @@ -523,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) { @@ -762,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; @@ -781,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; @@ -847,6 +852,7 @@ 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); @@ -916,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) @@ -951,8 +983,8 @@ 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 || behavior == EBhDisable) - intermediate.updateRequestedExtension(extension, behavior); + if (behavior != EBhDisable) + intermediate.addRequestedExtension(extension); iter->second = behavior; } } diff --git a/src/libraries/glslang/glslang/MachineIndependent/Versions.h b/src/libraries/glslang/glslang/MachineIndependent/Versions.h index 29bb44933..217fc2b48 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/Versions.h +++ b/src/libraries/glslang/glslang/MachineIndependent/Versions.h @@ -299,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 69f7f8e0b..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 69 "glslang.y" /* yacc.c:339 */ +#line 69 "MachineIndependent/glslang.y" /* yacc.c:339 */ /* Based on: @@ -88,7 +88,7 @@ Jutta Degener, 1995 using namespace glslang; -#line 92 "glslang_tab.cpp" /* yacc.c:339 */ +#line 92 "MachineIndependent/glslang_tab.cpp" /* yacc.c:339 */ # ifndef YY_NULLPTR # if defined __cplusplus && 201103L <= __cplusplus @@ -108,8 +108,8 @@ using namespace glslang; /* In a future release of Bison, this section will be replaced by #include "glslang_tab.cpp.h". */ -#ifndef YY_YY_GLSLANG_TAB_CPP_H_INCLUDED -# define YY_YY_GLSLANG_TAB_CPP_H_INCLUDED +#ifndef YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED +# define YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 1 @@ -548,7 +548,7 @@ extern int yydebug; union YYSTYPE { -#line 97 "glslang.y" /* yacc.c:355 */ +#line 97 "MachineIndependent/glslang.y" /* yacc.c:355 */ struct { glslang::TSourceLoc loc; @@ -584,7 +584,7 @@ union YYSTYPE glslang::TArraySizes* typeParameters; } interm; -#line 588 "glslang_tab.cpp" /* yacc.c:355 */ +#line 588 "MachineIndependent/glslang_tab.cpp" /* yacc.c:355 */ }; typedef union YYSTYPE YYSTYPE; @@ -596,10 +596,10 @@ typedef union YYSTYPE YYSTYPE; int yyparse (glslang::TParseContext* pParseContext); -#endif /* !YY_YY_GLSLANG_TAB_CPP_H_INCLUDED */ +#endif /* !YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED */ /* Copy the second part of user declarations. */ -#line 133 "glslang.y" /* yacc.c:358 */ +#line 133 "MachineIndependent/glslang.y" /* yacc.c:358 */ /* windows only pragma */ @@ -615,7 +615,7 @@ int yyparse (glslang::TParseContext* pParseContext); extern int yylex(YYSTYPE*, TParseContext&); -#line 619 "glslang_tab.cpp" /* yacc.c:358 */ +#line 619 "MachineIndependent/glslang_tab.cpp" /* yacc.c:358 */ #ifdef short # undef short @@ -1012,8 +1012,8 @@ static const yytype_uint16 yyrline[] = 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, 3865, 3871, 3874, - 3879, 3882 + 3813, 3817, 3826, 3829, 3833, 3842, 3842, 3884, 3890, 3893, + 3898, 3901 }; #endif @@ -4221,260 +4221,260 @@ yyreduce: switch (yyn) { case 2: -#line 357 "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 4229 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4229 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 3: -#line 363 "glslang.y" /* yacc.c:1646 */ +#line 363 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4237 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4237 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 4: -#line 366 "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 4247 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4247 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 5: -#line 371 "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 4255 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4255 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 6: -#line 374 "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 4263 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4263 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 7: -#line 377 "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 4272 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4272 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 8: -#line 381 "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 4280 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4280 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 9: -#line 385 "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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4288 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 10: -#line 388 "glslang.y" /* yacc.c:1646 */ +#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 4297 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4297 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 11: -#line 392 "glslang.y" /* yacc.c:1646 */ +#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 4306 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4306 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 12: -#line 396 "glslang.y" /* yacc.c:1646 */ +#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 4315 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4315 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 13: -#line 400 "glslang.y" /* yacc.c:1646 */ +#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 4324 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4324 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 14: -#line 404 "glslang.y" /* yacc.c:1646 */ +#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 4333 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4333 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 15: -#line 408 "glslang.y" /* yacc.c:1646 */ +#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 4342 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4342 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 16: -#line 412 "glslang.y" /* yacc.c:1646 */ +#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 4353 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4353 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 17: -#line 418 "glslang.y" /* yacc.c:1646 */ +#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 4362 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4362 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 18: -#line 426 "glslang.y" /* yacc.c:1646 */ +#line 426 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4370 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4370 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 19: -#line 429 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4378 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 20: -#line 432 "glslang.y" /* yacc.c:1646 */ +#line 432 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4386 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4386 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 21: -#line 435 "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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4394 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 22: -#line 438 "glslang.y" /* yacc.c:1646 */ +#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 4404 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4404 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 23: -#line 443 "glslang.y" /* yacc.c:1646 */ +#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 4414 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4414 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 24: -#line 451 "glslang.y" /* yacc.c:1646 */ +#line 451 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.integerCheck((yyvsp[0].interm.intermTypedNode), "[]"); (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4423 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4423 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 25: -#line 458 "glslang.y" /* yacc.c:1646 */ +#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 4432 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4432 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 26: -#line 465 "glslang.y" /* yacc.c:1646 */ +#line 465 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[0].interm); } -#line 4440 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4440 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 27: -#line 471 "glslang.y" /* yacc.c:1646 */ +#line 471 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[-1].interm); (yyval.interm).loc = (yyvsp[0].lex).loc; } -#line 4449 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4449 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 28: -#line 475 "glslang.y" /* yacc.c:1646 */ +#line 475 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[-1].interm); (yyval.interm).loc = (yyvsp[0].lex).loc; } -#line 4458 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4458 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 29: -#line 482 "glslang.y" /* yacc.c:1646 */ +#line 482 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[-1].interm); } -#line 4466 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4466 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 30: -#line 485 "glslang.y" /* yacc.c:1646 */ +#line 485 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[0].interm); } -#line 4474 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4474 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 31: -#line 491 "glslang.y" /* yacc.c:1646 */ +#line 491 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { TParameter param = { 0, new TType }; param.type->shallowCopy((yyvsp[0].interm.intermTypedNode)->getType()); @@ -4482,11 +4482,11 @@ yyreduce: (yyval.interm).function = (yyvsp[-1].interm).function; (yyval.interm).intermNode = (yyvsp[0].interm.intermTypedNode); } -#line 4486 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4486 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 32: -#line 498 "glslang.y" /* yacc.c:1646 */ +#line 498 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { TParameter param = { 0, new TType }; param.type->shallowCopy((yyvsp[0].interm.intermTypedNode)->getType()); @@ -4494,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 4498 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4498 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 33: -#line 508 "glslang.y" /* yacc.c:1646 */ +#line 508 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[-1].interm); } -#line 4506 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4506 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 34: -#line 516 "glslang.y" /* yacc.c:1646 */ +#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 4516 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4516 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 35: -#line 521 "glslang.y" /* yacc.c:1646 */ +#line 521 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // // Should be a method or subroutine call, but we haven't recognized the arguments yet. @@ -4544,50 +4544,50 @@ yyreduce: (yyval.interm).function = new TFunction(empty, TType(EbtVoid), EOpNull); } } -#line 4548 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4548 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 36: -#line 549 "glslang.y" /* yacc.c:1646 */ +#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 4558 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4558 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 37: -#line 558 "glslang.y" /* yacc.c:1646 */ +#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 4569 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4569 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 38: -#line 564 "glslang.y" /* yacc.c:1646 */ +#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 4578 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4578 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 39: -#line 568 "glslang.y" /* yacc.c:1646 */ +#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 4587 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4587 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 40: -#line 572 "glslang.y" /* yacc.c:1646 */ +#line 572 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if ((yyvsp[-1].interm).op != EOpNull) { char errorOp[2] = {0, 0}; @@ -4604,179 +4604,179 @@ yyreduce: (yyval.interm.intermTypedNode)->getAsConstantUnion()->setExpression(); } } -#line 4608 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4608 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 41: -#line 592 "glslang.y" /* yacc.c:1646 */ +#line 592 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpNull; } -#line 4614 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4614 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 42: -#line 593 "glslang.y" /* yacc.c:1646 */ +#line 593 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpNegative; } -#line 4620 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4620 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 43: -#line 594 "glslang.y" /* yacc.c:1646 */ +#line 594 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpLogicalNot; } -#line 4626 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4626 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 44: -#line 595 "glslang.y" /* 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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4633 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 45: -#line 601 "glslang.y" /* yacc.c:1646 */ +#line 601 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4639 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4639 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 46: -#line 602 "glslang.y" /* yacc.c:1646 */ +#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 4649 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4649 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 47: -#line 607 "glslang.y" /* yacc.c:1646 */ +#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 4659 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4659 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 48: -#line 612 "glslang.y" /* yacc.c:1646 */ +#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 4670 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4670 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 49: -#line 621 "glslang.y" /* yacc.c:1646 */ +#line 621 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4676 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4676 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 50: -#line 622 "glslang.y" /* yacc.c:1646 */ +#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 4686 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4686 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 51: -#line 627 "glslang.y" /* yacc.c:1646 */ +#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 4696 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4696 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 52: -#line 635 "glslang.y" /* yacc.c:1646 */ +#line 635 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4702 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4702 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 53: -#line 636 "glslang.y" /* yacc.c:1646 */ +#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 4713 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4713 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 54: -#line 642 "glslang.y" /* yacc.c:1646 */ +#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 4724 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4724 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 55: -#line 651 "glslang.y" /* yacc.c:1646 */ +#line 651 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4730 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4730 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 56: -#line 652 "glslang.y" /* yacc.c:1646 */ +#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 4740 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4740 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 57: -#line 657 "glslang.y" /* yacc.c:1646 */ +#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 4750 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4750 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 58: -#line 662 "glslang.y" /* yacc.c:1646 */ +#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 4760 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4760 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 59: -#line 667 "glslang.y" /* yacc.c:1646 */ +#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 4770 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4770 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 60: -#line 675 "glslang.y" /* yacc.c:1646 */ +#line 675 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4776 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4776 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 61: -#line 676 "glslang.y" /* yacc.c:1646 */ +#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(), "=="); @@ -4786,11 +4786,11 @@ yyreduce: if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 4790 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4790 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 62: -#line 685 "glslang.y" /* yacc.c:1646 */ +#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(), "!="); @@ -4800,124 +4800,124 @@ yyreduce: if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 4804 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4804 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 63: -#line 697 "glslang.y" /* yacc.c:1646 */ +#line 697 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4810 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4810 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 64: -#line 698 "glslang.y" /* yacc.c:1646 */ +#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 4821 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4821 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 65: -#line 707 "glslang.y" /* yacc.c:1646 */ +#line 707 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4827 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4827 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 66: -#line 708 "glslang.y" /* yacc.c:1646 */ +#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 4838 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4838 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 67: -#line 717 "glslang.y" /* yacc.c:1646 */ +#line 717 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4844 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4844 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 68: -#line 718 "glslang.y" /* yacc.c:1646 */ +#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 4855 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4855 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 69: -#line 727 "glslang.y" /* yacc.c:1646 */ +#line 727 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4861 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4861 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 70: -#line 728 "glslang.y" /* yacc.c:1646 */ +#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 4871 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4871 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 71: -#line 736 "glslang.y" /* yacc.c:1646 */ +#line 736 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4877 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4877 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 72: -#line 737 "glslang.y" /* yacc.c:1646 */ +#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 4887 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4887 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 73: -#line 745 "glslang.y" /* yacc.c:1646 */ +#line 745 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4893 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4893 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 74: -#line 746 "glslang.y" /* yacc.c:1646 */ +#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 4903 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4903 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 75: -#line 754 "glslang.y" /* yacc.c:1646 */ +#line 754 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4909 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4909 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 76: -#line 755 "glslang.y" /* yacc.c:1646 */ +#line 755 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { ++parseContext.controlFlowNestingLevel; } -#line 4917 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4917 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 77: -#line 758 "glslang.y" /* yacc.c:1646 */ +#line 758 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { --parseContext.controlFlowNestingLevel; parseContext.boolCheck((yyvsp[-4].lex).loc, (yyvsp[-5].interm.intermTypedNode)); @@ -4930,17 +4930,17 @@ yyreduce: (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } } -#line 4934 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4934 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 78: -#line 773 "glslang.y" /* yacc.c:1646 */ +#line 773 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4940 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4940 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 79: -#line 774 "glslang.y" /* yacc.c:1646 */ +#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(), "="); @@ -4948,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 4958 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4958 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 80: -#line 790 "glslang.y" /* yacc.c:1646 */ +#line 790 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpAssign; } -#line 4967 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4967 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 81: -#line 794 "glslang.y" /* yacc.c:1646 */ +#line 794 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpMulAssign; } -#line 4976 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4976 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 82: -#line 798 "glslang.y" /* yacc.c:1646 */ +#line 798 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpDivAssign; } -#line 4985 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4985 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 83: -#line 802 "glslang.y" /* yacc.c:1646 */ +#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 4995 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 4995 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 84: -#line 807 "glslang.y" /* yacc.c:1646 */ +#line 807 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpAddAssign; } -#line 5004 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5004 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 85: -#line 811 "glslang.y" /* yacc.c:1646 */ +#line 811 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpSubAssign; } -#line 5013 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5013 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 86: -#line 815 "glslang.y" /* yacc.c:1646 */ +#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 5022 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5022 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 87: -#line 819 "glslang.y" /* yacc.c:1646 */ +#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 5031 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5031 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 88: -#line 823 "glslang.y" /* yacc.c:1646 */ +#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 5040 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5040 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 89: -#line 827 "glslang.y" /* yacc.c:1646 */ +#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 5049 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5049 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 90: -#line 831 "glslang.y" /* yacc.c:1646 */ +#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 5058 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5058 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 91: -#line 838 "glslang.y" /* yacc.c:1646 */ +#line 838 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5066 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5066 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 92: -#line 841 "glslang.y" /* yacc.c:1646 */ +#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); @@ -5075,40 +5075,40 @@ yyreduce: (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } } -#line 5079 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5079 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 93: -#line 852 "glslang.y" /* yacc.c:1646 */ +#line 852 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.constantValueCheck((yyvsp[0].interm.intermTypedNode), ""); (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5088 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5088 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 94: -#line 859 "glslang.y" /* yacc.c:1646 */ +#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 5098 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5098 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 95: -#line 864 "glslang.y" /* yacc.c:1646 */ +#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 5108 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5108 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 96: -#line 869 "glslang.y" /* yacc.c:1646 */ +#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 @@ -5116,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 5120 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5120 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 97: -#line 876 "glslang.y" /* yacc.c:1646 */ +#line 876 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.declareBlock((yyvsp[-1].interm).loc, *(yyvsp[-1].interm).typeList); (yyval.interm.intermNode) = 0; } -#line 5129 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5129 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 98: -#line 880 "glslang.y" /* yacc.c:1646 */ +#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 5138 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5138 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 99: -#line 884 "glslang.y" /* yacc.c:1646 */ +#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 5147 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5147 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 100: -#line 888 "glslang.y" /* yacc.c:1646 */ +#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 5157 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5157 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 101: -#line 893 "glslang.y" /* yacc.c:1646 */ +#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 5167 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5167 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 102: -#line 898 "glslang.y" /* yacc.c:1646 */ +#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 5178 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5178 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 103: -#line 907 "glslang.y" /* yacc.c:1646 */ +#line 907 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.nestedBlockCheck((yyvsp[-2].interm.type).loc); } -#line 5184 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5184 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 104: -#line 907 "glslang.y" /* yacc.c:1646 */ +#line 907 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { --parseContext.structNestingLevel; parseContext.blockName = (yyvsp[-4].lex).string; @@ -5194,54 +5194,54 @@ yyreduce: (yyval.interm).loc = (yyvsp[-5].interm.type).loc; (yyval.interm).typeList = (yyvsp[-1].interm.typeList); } -#line 5198 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5198 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 105: -#line 918 "glslang.y" /* yacc.c:1646 */ +#line 918 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.identifierList) = new TIdentifierList; (yyval.interm.identifierList)->push_back((yyvsp[0].lex).string); } -#line 5207 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5207 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 106: -#line 922 "glslang.y" /* yacc.c:1646 */ +#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 5216 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5216 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 107: -#line 929 "glslang.y" /* yacc.c:1646 */ +#line 929 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).function = (yyvsp[-1].interm.function); (yyval.interm).loc = (yyvsp[0].lex).loc; } -#line 5225 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5225 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 108: -#line 936 "glslang.y" /* yacc.c:1646 */ +#line 936 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.function) = (yyvsp[0].interm.function); } -#line 5233 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5233 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 109: -#line 939 "glslang.y" /* yacc.c:1646 */ +#line 939 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.function) = (yyvsp[0].interm.function); } -#line 5241 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5241 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 110: -#line 946 "glslang.y" /* yacc.c:1646 */ +#line 946 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // Add the parameter (yyval.interm.function) = (yyvsp[-1].interm.function); @@ -5250,11 +5250,11 @@ yyreduce: else delete (yyvsp[0].interm).param.type; } -#line 5254 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5254 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 111: -#line 954 "glslang.y" /* yacc.c:1646 */ +#line 954 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // // Only first parameter of one-parameter functions can be void @@ -5272,11 +5272,11 @@ yyreduce: (yyvsp[-2].interm.function)->addParameter((yyvsp[0].interm).param); } } -#line 5276 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5276 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 112: -#line 974 "glslang.y" /* yacc.c:1646 */ +#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", @@ -5296,11 +5296,11 @@ yyreduce: function = new TFunction((yyvsp[-1].lex).string, type); (yyval.interm.function) = function; } -#line 5300 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5300 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 113: -#line 997 "glslang.y" /* yacc.c:1646 */ +#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"); @@ -5316,11 +5316,11 @@ yyreduce: (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).param = param; } -#line 5320 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5320 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 114: -#line 1012 "glslang.y" /* yacc.c:1646 */ +#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"); @@ -5340,11 +5340,11 @@ yyreduce: (yyval.interm).loc = (yyvsp[-1].lex).loc; (yyval.interm).param = param; } -#line 5344 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5344 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 115: -#line 1037 "glslang.y" /* yacc.c:1646 */ +#line 1037 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[0].interm); if ((yyvsp[-1].interm.type).qualifier.precision != EpqNone) @@ -5356,11 +5356,11 @@ yyreduce: parseContext.paramCheckFix((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, *(yyval.interm).param.type); } -#line 5360 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5360 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 116: -#line 1048 "glslang.y" /* yacc.c:1646 */ +#line 1048 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[0].interm); @@ -5368,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 5372 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5372 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 117: -#line 1058 "glslang.y" /* yacc.c:1646 */ +#line 1058 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[0].interm); if ((yyvsp[-1].interm.type).qualifier.precision != EpqNone) @@ -5383,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 5387 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5387 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 118: -#line 1068 "glslang.y" /* yacc.c:1646 */ +#line 1068 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[0].interm); @@ -5395,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 5399 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5399 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 119: -#line 1078 "glslang.y" /* yacc.c:1646 */ +#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 5410 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5410 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 120: -#line 1087 "glslang.y" /* yacc.c:1646 */ +#line 1087 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[0].interm); } -#line 5418 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5418 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 121: -#line 1090 "glslang.y" /* yacc.c:1646 */ +#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 5427 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5427 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 122: -#line 1094 "glslang.y" /* yacc.c:1646 */ +#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 5436 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5436 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 123: -#line 1098 "glslang.y" /* yacc.c:1646 */ +#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 5446 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5446 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 124: -#line 1103 "glslang.y" /* yacc.c:1646 */ +#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 5456 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5456 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 125: -#line 1111 "glslang.y" /* yacc.c:1646 */ +#line 1111 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).type = (yyvsp[0].interm.type); (yyval.interm).intermNode = 0; @@ -5464,51 +5464,51 @@ yyreduce: parseContext.declareTypeDefaults((yyval.interm).loc, (yyval.interm).type); } -#line 5468 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5468 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 126: -#line 1118 "glslang.y" /* yacc.c:1646 */ +#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 5478 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5478 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 127: -#line 1123 "glslang.y" /* yacc.c:1646 */ +#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 5488 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5488 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 128: -#line 1128 "glslang.y" /* yacc.c:1646 */ +#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 5498 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5498 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 129: -#line 1133 "glslang.y" /* yacc.c:1646 */ +#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 5508 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5508 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 130: -#line 1142 "glslang.y" /* yacc.c:1646 */ +#line 1142 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type) = (yyvsp[0].interm.type); @@ -5519,11 +5519,11 @@ yyreduce: } parseContext.precisionQualifierCheck((yyval.interm.type).loc, (yyval.interm.type).basicType, (yyval.interm.type).qualifier); } -#line 5523 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5523 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 131: -#line 1152 "glslang.y" /* yacc.c:1646 */ +#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)); @@ -5548,22 +5548,22 @@ yyreduce: (parseContext.language == EShLangFragment && (yyval.interm.type).qualifier.storage == EvqVaryingIn))) (yyval.interm.type).qualifier.smooth = true; } -#line 5552 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5552 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 132: -#line 1179 "glslang.y" /* yacc.c:1646 */ +#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 5563 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5563 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 133: -#line 1188 "glslang.y" /* yacc.c:1646 */ +#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"); @@ -5571,11 +5571,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.smooth = true; } -#line 5575 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5575 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 134: -#line 1195 "glslang.y" /* yacc.c:1646 */ +#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"); @@ -5583,11 +5583,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.flat = true; } -#line 5587 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5587 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 135: -#line 1203 "glslang.y" /* yacc.c:1646 */ +#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"); @@ -5595,11 +5595,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.nopersp = true; } -#line 5599 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5599 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 136: -#line 1210 "glslang.y" /* yacc.c:1646 */ +#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"); @@ -5607,11 +5607,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.explicitInterp = true; } -#line 5611 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5611 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 137: -#line 1217 "glslang.y" /* yacc.c:1646 */ +#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"); @@ -5620,11 +5620,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.pervertexNV = true; } -#line 5624 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5624 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 138: -#line 1225 "glslang.y" /* yacc.c:1646 */ +#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"); @@ -5635,11 +5635,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.perPrimitiveNV = true; } -#line 5639 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5639 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 139: -#line 1235 "glslang.y" /* yacc.c:1646 */ +#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"); @@ -5647,11 +5647,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.perViewNV = true; } -#line 5651 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5651 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 140: -#line 1242 "glslang.y" /* yacc.c:1646 */ +#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"); @@ -5659,84 +5659,84 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.perTaskNV = true; } -#line 5663 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5663 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 141: -#line 1253 "glslang.y" /* yacc.c:1646 */ +#line 1253 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type) = (yyvsp[-1].interm.type); } -#line 5671 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5671 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 142: -#line 1259 "glslang.y" /* yacc.c:1646 */ +#line 1259 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 5679 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5679 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 143: -#line 1262 "glslang.y" /* yacc.c:1646 */ +#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 5689 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5689 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 144: -#line 1269 "glslang.y" /* yacc.c:1646 */ +#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 5698 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5698 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 145: -#line 1273 "glslang.y" /* yacc.c:1646 */ +#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 5707 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5707 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 146: -#line 1277 "glslang.y" /* yacc.c:1646 */ +#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 5717 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5717 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 147: -#line 1286 "glslang.y" /* yacc.c:1646 */ +#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 5728 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5728 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 148: -#line 1296 "glslang.y" /* yacc.c:1646 */ +#line 1296 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 5736 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5736 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 149: -#line 1299 "glslang.y" /* yacc.c:1646 */ +#line 1299 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type) = (yyvsp[-1].interm.type); if ((yyval.interm.type).basicType == EbtVoid) @@ -5745,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 5749 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5749 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 150: -#line 1310 "glslang.y" /* yacc.c:1646 */ +#line 1310 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 5757 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5757 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 151: -#line 1313 "glslang.y" /* yacc.c:1646 */ +#line 1313 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 5765 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5765 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 152: -#line 1316 "glslang.y" /* yacc.c:1646 */ +#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 5774 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5774 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 153: -#line 1320 "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 5783 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5783 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 154: -#line 1324 "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 5792 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5792 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 155: -#line 1329 "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 5801 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5801 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 156: -#line 1333 "glslang.y" /* yacc.c:1646 */ +#line 1333 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 5809 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5809 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 157: -#line 1340 "glslang.y" /* yacc.c:1646 */ +#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 5818 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5818 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 158: -#line 1344 "glslang.y" /* yacc.c:1646 */ +#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 5828 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5828 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 159: -#line 1349 "glslang.y" /* yacc.c:1646 */ +#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 5839 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5839 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 160: -#line 1355 "glslang.y" /* yacc.c:1646 */ +#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 5850 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5850 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 161: -#line 1361 "glslang.y" /* yacc.c:1646 */ +#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"); @@ -5858,21 +5858,21 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.centroid = true; } -#line 5862 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5862 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 162: -#line 1368 "glslang.y" /* yacc.c:1646 */ +#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 5872 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5872 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 163: -#line 1373 "glslang.y" /* yacc.c:1646 */ +#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"); @@ -5881,21 +5881,21 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqShared; } -#line 5885 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5885 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 164: -#line 1381 "glslang.y" /* yacc.c:1646 */ +#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 5895 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5895 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 165: -#line 1387 "glslang.y" /* yacc.c:1646 */ +#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"); @@ -5908,11 +5908,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqVaryingIn; } -#line 5912 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5912 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 166: -#line 1399 "glslang.y" /* yacc.c:1646 */ +#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"); @@ -5927,32 +5927,32 @@ yyreduce: else (yyval.interm.type).qualifier.storage = EvqVaryingIn; } -#line 5931 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5931 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 167: -#line 1413 "glslang.y" /* yacc.c:1646 */ +#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 5942 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5942 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 168: -#line 1419 "glslang.y" /* yacc.c:1646 */ +#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 5952 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5952 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 169: -#line 1424 "glslang.y" /* yacc.c:1646 */ +#line 1424 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "hitAttributeNV"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangIntersectMask | EShLangClosestHitMask @@ -5961,11 +5961,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqHitAttr; } -#line 5965 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5965 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 170: -#line 1432 "glslang.y" /* yacc.c:1646 */ +#line 1432 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "hitAttributeEXT"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangIntersectMask | EShLangClosestHitMask @@ -5974,11 +5974,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqHitAttr; } -#line 5978 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5978 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 171: -#line 1440 "glslang.y" /* yacc.c:1646 */ +#line 1440 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "rayPayloadNV"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask | @@ -5987,11 +5987,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqPayload; } -#line 5991 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 5991 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 172: -#line 1448 "glslang.y" /* yacc.c:1646 */ +#line 1448 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "rayPayloadEXT"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask | @@ -6000,11 +6000,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqPayload; } -#line 6004 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6004 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 173: -#line 1456 "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 | @@ -6013,11 +6013,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqPayloadIn; } -#line 6017 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6017 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 174: -#line 1464 "glslang.y" /* yacc.c:1646 */ +#line 1464 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "rayPayloadInEXT"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangClosestHitMask | @@ -6026,11 +6026,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqPayloadIn; } -#line 6030 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6030 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 175: -#line 1472 "glslang.y" /* yacc.c:1646 */ +#line 1472 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataNV"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenMask | @@ -6039,11 +6039,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqCallableData; } -#line 6043 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6043 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 176: -#line 1480 "glslang.y" /* yacc.c:1646 */ +#line 1480 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataEXT"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenMask | @@ -6052,11 +6052,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqCallableData; } -#line 6056 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6056 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 177: -#line 1488 "glslang.y" /* yacc.c:1646 */ +#line 1488 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataInNV"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangCallableMask), "callableDataInNV"); @@ -6064,11 +6064,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqCallableDataIn; } -#line 6068 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6068 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 178: -#line 1495 "glslang.y" /* yacc.c:1646 */ +#line 1495 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataInEXT"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangCallableMask), "callableDataInEXT"); @@ -6076,175 +6076,175 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqCallableDataIn; } -#line 6080 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6080 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 179: -#line 1502 "glslang.y" /* yacc.c:1646 */ +#line 1502 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.coherent = true; } -#line 6089 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6089 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 180: -#line 1506 "glslang.y" /* yacc.c:1646 */ +#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 6099 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6099 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 181: -#line 1511 "glslang.y" /* yacc.c:1646 */ +#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 6109 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6109 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 182: -#line 1516 "glslang.y" /* yacc.c:1646 */ +#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 6119 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6119 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 183: -#line 1521 "glslang.y" /* yacc.c:1646 */ +#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 6129 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6129 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 184: -#line 1526 "glslang.y" /* yacc.c:1646 */ +#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 6139 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6139 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 185: -#line 1531 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6149 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 186: -#line 1536 "glslang.y" /* yacc.c:1646 */ +#line 1536 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.volatil = true; } -#line 6158 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6158 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 187: -#line 1540 "glslang.y" /* yacc.c:1646 */ +#line 1540 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.restrict = true; } -#line 6167 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6167 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 188: -#line 1544 "glslang.y" /* yacc.c:1646 */ +#line 1544 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.readonly = true; } -#line 6176 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6176 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 189: -#line 1548 "glslang.y" /* yacc.c:1646 */ +#line 1548 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.writeonly = true; } -#line 6185 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6185 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 190: -#line 1552 "glslang.y" /* yacc.c:1646 */ +#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 6196 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6196 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 191: -#line 1558 "glslang.y" /* yacc.c:1646 */ +#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 6207 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6207 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 192: -#line 1569 "glslang.y" /* yacc.c:1646 */ +#line 1569 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.nonUniform = true; } -#line 6216 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6216 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 193: -#line 1576 "glslang.y" /* yacc.c:1646 */ +#line 1576 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // TODO } -#line 6224 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6224 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 194: -#line 1579 "glslang.y" /* yacc.c:1646 */ +#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 6234 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6234 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 195: -#line 1588 "glslang.y" /* yacc.c:1646 */ +#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 6244 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6244 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 196: -#line 1593 "glslang.y" /* yacc.c:1646 */ +#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); @@ -6252,21 +6252,21 @@ yyreduce: (yyval.interm.type).typeParameters = (yyvsp[-1].interm.typeParameters); (yyval.interm.type).arraySizes = (yyvsp[0].interm).arraySizes; } -#line 6256 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6256 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 197: -#line 1603 "glslang.y" /* yacc.c:1646 */ +#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 6266 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6266 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 198: -#line 1608 "glslang.y" /* yacc.c:1646 */ +#line 1608 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[-2].lex).loc; (yyval.interm).arraySizes = new TArraySizes; @@ -6275,20 +6275,20 @@ yyreduce: parseContext.arraySizeCheck((yyvsp[-1].interm.intermTypedNode)->getLoc(), (yyvsp[-1].interm.intermTypedNode), size, "array size"); (yyval.interm).arraySizes->addInnerSize(size); } -#line 6279 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6279 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 199: -#line 1616 "glslang.y" /* yacc.c:1646 */ +#line 1616 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[-2].interm); (yyval.interm).arraySizes->addInnerSize(); } -#line 6288 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6288 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 200: -#line 1620 "glslang.y" /* yacc.c:1646 */ +#line 1620 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[-3].interm); @@ -6296,35 +6296,35 @@ yyreduce: parseContext.arraySizeCheck((yyvsp[-1].interm.intermTypedNode)->getLoc(), (yyvsp[-1].interm.intermTypedNode), size, "array size"); (yyval.interm).arraySizes->addInnerSize(size); } -#line 6300 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6300 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 201: -#line 1630 "glslang.y" /* yacc.c:1646 */ +#line 1630 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeParameters) = (yyvsp[0].interm.typeParameters); } -#line 6308 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6308 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 202: -#line 1633 "glslang.y" /* yacc.c:1646 */ +#line 1633 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeParameters) = 0; } -#line 6316 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6316 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 203: -#line 1639 "glslang.y" /* yacc.c:1646 */ +#line 1639 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeParameters) = (yyvsp[-1].interm.typeParameters); } -#line 6324 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6324 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 204: -#line 1645 "glslang.y" /* yacc.c:1646 */ +#line 1645 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeParameters) = new TArraySizes; @@ -6332,11 +6332,11 @@ yyreduce: parseContext.arraySizeCheck((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode), size, "type parameter"); (yyval.interm.typeParameters)->addInnerSize(size); } -#line 6336 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6336 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 205: -#line 1652 "glslang.y" /* yacc.c:1646 */ +#line 1652 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeParameters) = (yyvsp[-2].interm.typeParameters); @@ -6344,300 +6344,300 @@ yyreduce: parseContext.arraySizeCheck((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode), size, "type parameter"); (yyval.interm.typeParameters)->addInnerSize(size); } -#line 6348 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6348 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 206: -#line 1662 "glslang.y" /* yacc.c:1646 */ +#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 6357 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6357 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 207: -#line 1666 "glslang.y" /* yacc.c:1646 */ +#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 6366 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6366 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 208: -#line 1670 "glslang.y" /* yacc.c:1646 */ +#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 6375 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6375 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 209: -#line 1674 "glslang.y" /* yacc.c:1646 */ +#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 6385 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6385 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 210: -#line 1679 "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 = EbtBool; } -#line 6394 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6394 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 211: -#line 1683 "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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6404 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 212: -#line 1688 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6414 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 213: -#line 1693 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6424 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 214: -#line 1698 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6434 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 215: -#line 1703 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6444 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 216: -#line 1708 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6454 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 217: -#line 1713 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6464 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 218: -#line 1718 "glslang.y" /* yacc.c:1646 */ +#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 6474 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6474 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 219: -#line 1723 "glslang.y" /* yacc.c:1646 */ +#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 6484 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6484 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 220: -#line 1728 "glslang.y" /* yacc.c:1646 */ +#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 6495 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6495 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 221: -#line 1734 "glslang.y" /* yacc.c:1646 */ +#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 6506 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6506 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 222: -#line 1740 "glslang.y" /* yacc.c:1646 */ +#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 6517 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6517 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 223: -#line 1746 "glslang.y" /* yacc.c:1646 */ +#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 6527 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6527 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 224: -#line 1751 "glslang.y" /* yacc.c:1646 */ +#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 6537 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6537 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 225: -#line 1756 "glslang.y" /* yacc.c:1646 */ +#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 6547 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6547 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 226: -#line 1761 "glslang.y" /* yacc.c:1646 */ +#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 6557 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6557 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 227: -#line 1766 "glslang.y" /* yacc.c:1646 */ +#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 6567 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6567 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 228: -#line 1771 "glslang.y" /* yacc.c:1646 */ +#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 6577 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6577 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 229: -#line 1776 "glslang.y" /* yacc.c:1646 */ +#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 6587 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6587 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 230: -#line 1781 "glslang.y" /* yacc.c:1646 */ +#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 6597 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6597 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 231: -#line 1786 "glslang.y" /* yacc.c:1646 */ +#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 6607 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6607 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 232: -#line 1791 "glslang.y" /* yacc.c:1646 */ +#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 6617 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6617 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 233: -#line 1796 "glslang.y" /* yacc.c:1646 */ +#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 6627 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6627 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 234: -#line 1801 "glslang.y" /* yacc.c:1646 */ +#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 6637 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6637 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 235: -#line 1807 "glslang.y" /* yacc.c:1646 */ +#line 1807 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -6645,121 +6645,121 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; } -#line 6649 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6649 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 236: -#line 1814 "glslang.y" /* yacc.c:1646 */ +#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 6659 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6659 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 237: -#line 1819 "glslang.y" /* yacc.c:1646 */ +#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 6669 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6669 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 238: -#line 1824 "glslang.y" /* yacc.c:1646 */ +#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 6679 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6679 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 239: -#line 1829 "glslang.y" /* yacc.c:1646 */ +#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 6689 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6689 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 240: -#line 1834 "glslang.y" /* yacc.c:1646 */ +#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 6699 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6699 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 241: -#line 1839 "glslang.y" /* yacc.c:1646 */ +#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 6709 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6709 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 242: -#line 1844 "glslang.y" /* yacc.c:1646 */ +#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 6719 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6719 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 243: -#line 1849 "glslang.y" /* yacc.c:1646 */ +#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 6729 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6729 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 244: -#line 1854 "glslang.y" /* yacc.c:1646 */ +#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 6739 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6739 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 245: -#line 1859 "glslang.y" /* yacc.c:1646 */ +#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 6749 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6749 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 246: -#line 1864 "glslang.y" /* yacc.c:1646 */ +#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 6759 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6759 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 247: -#line 1869 "glslang.y" /* yacc.c:1646 */ +#line 1869 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double vector"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -6768,11 +6768,11 @@ yyreduce: (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setVector(2); } -#line 6772 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6772 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 248: -#line 1877 "glslang.y" /* yacc.c:1646 */ +#line 1877 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double vector"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -6781,11 +6781,11 @@ yyreduce: (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setVector(3); } -#line 6785 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6785 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 249: -#line 1885 "glslang.y" /* yacc.c:1646 */ +#line 1885 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double vector"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -6794,374 +6794,374 @@ yyreduce: (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setVector(4); } -#line 6798 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6798 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 250: -#line 1893 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6809 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 251: -#line 1899 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6820 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 252: -#line 1905 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6831 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 253: -#line 1911 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6842 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 254: -#line 1917 "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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6853 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 255: -#line 1923 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6864 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 256: -#line 1929 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6875 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 257: -#line 1935 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6886 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 258: -#line 1941 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6897 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 259: -#line 1947 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6908 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 260: -#line 1953 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6919 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 261: -#line 1959 "glslang.y" /* yacc.c:1646 */ +#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 6930 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6930 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 262: -#line 1965 "glslang.y" /* yacc.c:1646 */ +#line 1965 "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 6941 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6941 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 263: -#line 1971 "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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6952 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 264: -#line 1977 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6963 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 265: -#line 1983 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6974 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 266: -#line 1989 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6985 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 267: -#line 1995 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 6996 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 268: -#line 2001 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7007 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 269: -#line 2007 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7018 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 270: -#line 2013 "glslang.y" /* yacc.c:1646 */ +#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 7029 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7029 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 271: -#line 2019 "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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7040 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 272: -#line 2025 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7051 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 273: -#line 2031 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7062 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 274: -#line 2037 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7073 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 275: -#line 2043 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7084 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 276: -#line 2049 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7095 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 277: -#line 2055 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7106 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 278: -#line 2061 "glslang.y" /* yacc.c:1646 */ +#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 7117 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7117 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 279: -#line 2067 "glslang.y" /* yacc.c:1646 */ +#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 7128 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7128 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 280: -#line 2073 "glslang.y" /* yacc.c:1646 */ +#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 7139 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7139 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 281: -#line 2079 "glslang.y" /* yacc.c:1646 */ +#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 7150 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7150 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 282: -#line 2085 "glslang.y" /* yacc.c:1646 */ +#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 7161 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7161 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 283: -#line 2091 "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()) @@ -7170,11 +7170,11 @@ yyreduce: (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 2); } -#line 7174 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7174 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 284: -#line 2099 "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()) @@ -7183,11 +7183,11 @@ yyreduce: (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 3); } -#line 7187 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7187 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 285: -#line 2107 "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()) @@ -7196,11 +7196,11 @@ yyreduce: (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 4); } -#line 7200 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7200 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 286: -#line 2115 "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()) @@ -7209,11 +7209,11 @@ yyreduce: (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 2); } -#line 7213 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7213 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 287: -#line 2123 "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()) @@ -7222,11 +7222,11 @@ yyreduce: (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 3); } -#line 7226 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7226 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 288: -#line 2131 "glslang.y" /* yacc.c:1646 */ +#line 2131 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -7235,11 +7235,11 @@ yyreduce: (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 4); } -#line 7239 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7239 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 289: -#line 2139 "glslang.y" /* yacc.c:1646 */ +#line 2139 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -7248,11 +7248,11 @@ yyreduce: (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 2); } -#line 7252 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7252 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 290: -#line 2147 "glslang.y" /* yacc.c:1646 */ +#line 2147 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -7261,11 +7261,11 @@ yyreduce: (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 3); } -#line 7265 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7265 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 291: -#line 2155 "glslang.y" /* yacc.c:1646 */ +#line 2155 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -7274,11 +7274,11 @@ yyreduce: (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 4); } -#line 7278 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7278 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 292: -#line 2163 "glslang.y" /* yacc.c:1646 */ +#line 2163 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -7287,11 +7287,11 @@ yyreduce: (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 2); } -#line 7291 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7291 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 293: -#line 2171 "glslang.y" /* yacc.c:1646 */ +#line 2171 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -7300,11 +7300,11 @@ yyreduce: (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 3); } -#line 7304 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7304 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 294: -#line 2179 "glslang.y" /* yacc.c:1646 */ +#line 2179 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -7313,2008 +7313,2008 @@ yyreduce: (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 4); } -#line 7317 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7317 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 295: -#line 2187 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7328 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 296: -#line 2193 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7339 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 297: -#line 2199 "glslang.y" /* yacc.c:1646 */ +#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 7350 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7350 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 298: -#line 2205 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7361 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 299: -#line 2211 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7372 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 300: -#line 2217 "glslang.y" /* yacc.c:1646 */ +#line 2217 "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 7383 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7383 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 301: -#line 2223 "glslang.y" /* yacc.c:1646 */ +#line 2223 "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 7394 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7394 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 302: -#line 2229 "glslang.y" /* yacc.c:1646 */ +#line 2229 "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 7405 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7405 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 303: -#line 2235 "glslang.y" /* yacc.c:1646 */ +#line 2235 "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 7416 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7416 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 304: -#line 2241 "glslang.y" /* yacc.c:1646 */ +#line 2241 "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 7427 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7427 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 305: -#line 2247 "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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7438 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 306: -#line 2253 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7449 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 307: -#line 2259 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7460 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 308: -#line 2265 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7471 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 309: -#line 2271 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7482 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 310: -#line 2277 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7493 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 311: -#line 2283 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7504 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 312: -#line 2289 "glslang.y" /* yacc.c:1646 */ +#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 7515 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7515 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 313: -#line 2295 "glslang.y" /* yacc.c:1646 */ +#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 7526 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7526 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 314: -#line 2301 "glslang.y" /* yacc.c:1646 */ +#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 7537 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7537 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 315: -#line 2307 "glslang.y" /* yacc.c:1646 */ +#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 7548 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7548 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 316: -#line 2313 "glslang.y" /* yacc.c:1646 */ +#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 7559 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7559 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 317: -#line 2319 "glslang.y" /* yacc.c:1646 */ +#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 7570 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7570 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 318: -#line 2325 "glslang.y" /* yacc.c:1646 */ +#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 7581 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7581 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 319: -#line 2331 "glslang.y" /* yacc.c:1646 */ +#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 7592 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7592 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 320: -#line 2337 "glslang.y" /* yacc.c:1646 */ +#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 7603 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7603 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 321: -#line 2343 "glslang.y" /* yacc.c:1646 */ +#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 7614 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7614 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 322: -#line 2349 "glslang.y" /* yacc.c:1646 */ +#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 7625 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7625 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 323: -#line 2355 "glslang.y" /* yacc.c:1646 */ +#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 7636 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7636 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 324: -#line 2361 "glslang.y" /* yacc.c:1646 */ +#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 7647 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7647 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 325: -#line 2367 "glslang.y" /* yacc.c:1646 */ +#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 7658 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7658 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 326: -#line 2373 "glslang.y" /* yacc.c:1646 */ +#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 7669 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7669 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 327: -#line 2379 "glslang.y" /* yacc.c:1646 */ +#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 7680 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7680 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 328: -#line 2385 "glslang.y" /* yacc.c:1646 */ +#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 7691 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7691 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 329: -#line 2391 "glslang.y" /* yacc.c:1646 */ +#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 7702 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7702 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 330: -#line 2397 "glslang.y" /* yacc.c:1646 */ +#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 7713 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7713 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 331: -#line 2403 "glslang.y" /* yacc.c:1646 */ +#line 2403 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtAccStruct; } -#line 7722 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7722 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 332: -#line 2407 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7731 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 333: -#line 2411 "glslang.y" /* yacc.c:1646 */ +#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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7740 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 334: -#line 2415 "glslang.y" /* yacc.c:1646 */ +#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 7750 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7750 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 335: -#line 2420 "glslang.y" /* yacc.c:1646 */ +#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 7760 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7760 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 336: -#line 2426 "glslang.y" /* yacc.c:1646 */ +#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 7770 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7770 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 337: -#line 2431 "glslang.y" /* yacc.c:1646 */ +#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 7780 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7780 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 338: -#line 2436 "glslang.y" /* yacc.c:1646 */ +#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 7790 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7790 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 339: -#line 2441 "glslang.y" /* yacc.c:1646 */ +#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 7800 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7800 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 340: -#line 2446 "glslang.y" /* yacc.c:1646 */ +#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 7810 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7810 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 341: -#line 2451 "glslang.y" /* yacc.c:1646 */ +#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 7820 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7820 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 342: -#line 2456 "glslang.y" /* yacc.c:1646 */ +#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 7830 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7830 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 343: -#line 2462 "glslang.y" /* yacc.c:1646 */ +#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 7840 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7840 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 344: -#line 2467 "glslang.y" /* yacc.c:1646 */ +#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 7850 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7850 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 345: -#line 2472 "glslang.y" /* yacc.c:1646 */ +#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 7860 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7860 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 346: -#line 2477 "glslang.y" /* yacc.c:1646 */ +#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 7870 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7870 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 347: -#line 2482 "glslang.y" /* yacc.c:1646 */ +#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 7880 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7880 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 348: -#line 2487 "glslang.y" /* yacc.c:1646 */ +#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 7891 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7891 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 349: -#line 2493 "glslang.y" /* yacc.c:1646 */ +#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 7902 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7902 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 350: -#line 2499 "glslang.y" /* yacc.c:1646 */ +#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 7913 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7913 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 351: -#line 2505 "glslang.y" /* yacc.c:1646 */ +#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 7924 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7924 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 352: -#line 2511 "glslang.y" /* yacc.c:1646 */ +#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 7935 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7935 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 353: -#line 2517 "glslang.y" /* yacc.c:1646 */ +#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 7946 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7946 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 354: -#line 2523 "glslang.y" /* yacc.c:1646 */ +#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 7957 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7957 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 355: -#line 2529 "glslang.y" /* yacc.c:1646 */ +#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 7968 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7968 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 356: -#line 2535 "glslang.y" /* yacc.c:1646 */ +#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 7979 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7979 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 357: -#line 2541 "glslang.y" /* yacc.c:1646 */ +#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 7990 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 7990 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 358: -#line 2547 "glslang.y" /* yacc.c:1646 */ +#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 8001 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8001 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 359: -#line 2553 "glslang.y" /* yacc.c:1646 */ +#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 8012 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8012 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 360: -#line 2559 "glslang.y" /* yacc.c:1646 */ +#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 8023 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8023 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 361: -#line 2565 "glslang.y" /* yacc.c:1646 */ +#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 8033 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8033 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 362: -#line 2571 "glslang.y" /* yacc.c:1646 */ +#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 8043 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8043 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 363: -#line 2576 "glslang.y" /* yacc.c:1646 */ +#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 8053 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8053 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 364: -#line 2581 "glslang.y" /* yacc.c:1646 */ +#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 8063 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8063 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 365: -#line 2586 "glslang.y" /* yacc.c:1646 */ +#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 8073 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8073 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 366: -#line 2591 "glslang.y" /* yacc.c:1646 */ +#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 8083 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8083 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 367: -#line 2596 "glslang.y" /* yacc.c:1646 */ +#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 8093 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8093 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 368: -#line 2601 "glslang.y" /* yacc.c:1646 */ +#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 8103 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8103 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 369: -#line 2607 "glslang.y" /* yacc.c:1646 */ +#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 8113 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8113 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 370: -#line 2612 "glslang.y" /* yacc.c:1646 */ +#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 8123 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8123 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 371: -#line 2617 "glslang.y" /* yacc.c:1646 */ +#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 8133 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8133 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 372: -#line 2622 "glslang.y" /* yacc.c:1646 */ +#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 8143 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8143 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 373: -#line 2627 "glslang.y" /* yacc.c:1646 */ +#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 8153 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8153 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 374: -#line 2632 "glslang.y" /* yacc.c:1646 */ +#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 8163 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8163 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 375: -#line 2637 "glslang.y" /* yacc.c:1646 */ +#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 8173 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8173 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 376: -#line 2642 "glslang.y" /* yacc.c:1646 */ +#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 8183 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8183 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 377: -#line 2648 "glslang.y" /* yacc.c:1646 */ +#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 8193 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8193 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 378: -#line 2653 "glslang.y" /* yacc.c:1646 */ +#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 8203 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8203 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 379: -#line 2658 "glslang.y" /* yacc.c:1646 */ +#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 8213 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8213 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 380: -#line 2663 "glslang.y" /* yacc.c:1646 */ +#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 8223 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8223 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 381: -#line 2668 "glslang.y" /* yacc.c:1646 */ +#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 8233 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8233 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 382: -#line 2673 "glslang.y" /* yacc.c:1646 */ +#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 8243 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8243 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 383: -#line 2678 "glslang.y" /* yacc.c:1646 */ +#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 8253 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8253 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 384: -#line 2683 "glslang.y" /* yacc.c:1646 */ +#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 8263 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8263 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 385: -#line 2688 "glslang.y" /* yacc.c:1646 */ +#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 8273 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8273 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 386: -#line 2693 "glslang.y" /* yacc.c:1646 */ +#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 8283 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8283 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 387: -#line 2698 "glslang.y" /* yacc.c:1646 */ +#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 8293 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8293 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 388: -#line 2703 "glslang.y" /* yacc.c:1646 */ +#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 8303 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8303 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 389: -#line 2708 "glslang.y" /* yacc.c:1646 */ +#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 8313 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8313 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 390: -#line 2713 "glslang.y" /* yacc.c:1646 */ +#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 8323 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8323 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 391: -#line 2718 "glslang.y" /* yacc.c:1646 */ +#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 8333 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8333 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 392: -#line 2724 "glslang.y" /* yacc.c:1646 */ +#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 8343 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8343 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 393: -#line 2729 "glslang.y" /* yacc.c:1646 */ +#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 8353 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8353 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 394: -#line 2734 "glslang.y" /* yacc.c:1646 */ +#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 8364 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8364 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 395: -#line 2740 "glslang.y" /* yacc.c:1646 */ +#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 8375 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8375 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 396: -#line 2746 "glslang.y" /* yacc.c:1646 */ +#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 8385 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8385 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 397: -#line 2751 "glslang.y" /* yacc.c:1646 */ +#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 8395 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8395 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 398: -#line 2756 "glslang.y" /* yacc.c:1646 */ +#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 8405 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8405 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 399: -#line 2761 "glslang.y" /* yacc.c:1646 */ +#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 8416 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8416 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 400: -#line 2767 "glslang.y" /* yacc.c:1646 */ +#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 8426 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8426 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 401: -#line 2772 "glslang.y" /* yacc.c:1646 */ +#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 8436 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8436 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 402: -#line 2777 "glslang.y" /* yacc.c:1646 */ +#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 8446 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8446 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 403: -#line 2782 "glslang.y" /* yacc.c:1646 */ +#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 8457 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8457 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 404: -#line 2788 "glslang.y" /* yacc.c:1646 */ +#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 8467 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8467 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 405: -#line 2793 "glslang.y" /* yacc.c:1646 */ +#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 8477 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8477 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 406: -#line 2798 "glslang.y" /* yacc.c:1646 */ +#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 8487 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8487 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 407: -#line 2803 "glslang.y" /* yacc.c:1646 */ +#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 8498 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8498 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 408: -#line 2809 "glslang.y" /* yacc.c:1646 */ +#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 8508 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8508 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 409: -#line 2814 "glslang.y" /* yacc.c:1646 */ +#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 8518 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8518 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 410: -#line 2819 "glslang.y" /* yacc.c:1646 */ +#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 8528 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8528 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 411: -#line 2824 "glslang.y" /* yacc.c:1646 */ +#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 8539 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8539 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 412: -#line 2830 "glslang.y" /* yacc.c:1646 */ +#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 8550 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8550 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 413: -#line 2836 "glslang.y" /* yacc.c:1646 */ +#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 8561 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8561 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 414: -#line 2842 "glslang.y" /* yacc.c:1646 */ +#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 8572 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8572 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 415: -#line 2848 "glslang.y" /* yacc.c:1646 */ +#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 8582 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8582 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 416: -#line 2853 "glslang.y" /* yacc.c:1646 */ +#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 8593 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8593 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 417: -#line 2859 "glslang.y" /* yacc.c:1646 */ +#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 8604 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8604 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 418: -#line 2865 "glslang.y" /* yacc.c:1646 */ +#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 8615 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8615 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 419: -#line 2871 "glslang.y" /* yacc.c:1646 */ +#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 8625 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8625 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 420: -#line 2876 "glslang.y" /* yacc.c:1646 */ +#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 8635 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8635 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 421: -#line 2881 "glslang.y" /* yacc.c:1646 */ +#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 8645 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8645 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 422: -#line 2886 "glslang.y" /* yacc.c:1646 */ +#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 8655 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8655 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 423: -#line 2891 "glslang.y" /* yacc.c:1646 */ +#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 8665 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8665 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 424: -#line 2896 "glslang.y" /* yacc.c:1646 */ +#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 8676 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8676 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 425: -#line 2902 "glslang.y" /* yacc.c:1646 */ +#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 8686 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8686 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 426: -#line 2907 "glslang.y" /* yacc.c:1646 */ +#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 8696 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8696 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 427: -#line 2912 "glslang.y" /* yacc.c:1646 */ +#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 8706 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8706 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 428: -#line 2917 "glslang.y" /* yacc.c:1646 */ +#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 8717 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8717 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 429: -#line 2923 "glslang.y" /* yacc.c:1646 */ +#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 8727 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8727 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 430: -#line 2928 "glslang.y" /* yacc.c:1646 */ +#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 8737 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8737 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 431: -#line 2933 "glslang.y" /* yacc.c:1646 */ +#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 8747 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8747 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 432: -#line 2938 "glslang.y" /* yacc.c:1646 */ +#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 8758 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8758 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 433: -#line 2944 "glslang.y" /* yacc.c:1646 */ +#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 8768 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8768 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 434: -#line 2949 "glslang.y" /* yacc.c:1646 */ +#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 8778 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8778 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 435: -#line 2954 "glslang.y" /* yacc.c:1646 */ +#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 8788 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8788 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 436: -#line 2959 "glslang.y" /* yacc.c:1646 */ +#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 8799 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8799 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 437: -#line 2965 "glslang.y" /* yacc.c:1646 */ +#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 8809 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8809 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 438: -#line 2970 "glslang.y" /* yacc.c:1646 */ +#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 8819 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8819 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 439: -#line 2975 "glslang.y" /* yacc.c:1646 */ +#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 8829 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8829 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 440: -#line 2980 "glslang.y" /* yacc.c:1646 */ +#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 8840 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8840 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 441: -#line 2986 "glslang.y" /* yacc.c:1646 */ +#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 8850 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8850 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 442: -#line 2991 "glslang.y" /* yacc.c:1646 */ +#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 8860 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8860 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 443: -#line 2996 "glslang.y" /* yacc.c:1646 */ +#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 8870 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8870 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 444: -#line 3001 "glslang.y" /* yacc.c:1646 */ +#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 8881 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8881 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 445: -#line 3007 "glslang.y" /* yacc.c:1646 */ +#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 8891 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8891 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 446: -#line 3012 "glslang.y" /* yacc.c:1646 */ +#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 8901 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8901 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 447: -#line 3017 "glslang.y" /* yacc.c:1646 */ +#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 8911 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8911 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 448: -#line 3022 "glslang.y" /* yacc.c:1646 */ +#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 8922 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8922 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 449: -#line 3028 "glslang.y" /* yacc.c:1646 */ +#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 8932 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8932 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 450: -#line 3033 "glslang.y" /* yacc.c:1646 */ +#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 8942 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8942 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 451: -#line 3038 "glslang.y" /* yacc.c:1646 */ +#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 8952 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8952 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 452: -#line 3043 "glslang.y" /* yacc.c:1646 */ +#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 8963 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8963 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 453: -#line 3049 "glslang.y" /* yacc.c:1646 */ +#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 8973 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8973 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 454: -#line 3054 "glslang.y" /* yacc.c:1646 */ +#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 8983 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8983 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 455: -#line 3059 "glslang.y" /* yacc.c:1646 */ +#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 8993 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 8993 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 456: -#line 3064 "glslang.y" /* yacc.c:1646 */ +#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 9004 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9004 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 457: -#line 3070 "glslang.y" /* yacc.c:1646 */ +#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 9014 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9014 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 458: -#line 3075 "glslang.y" /* yacc.c:1646 */ +#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 9024 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9024 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 459: -#line 3080 "glslang.y" /* yacc.c:1646 */ +#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 9034 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9034 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 460: -#line 3085 "glslang.y" /* yacc.c:1646 */ +#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 9045 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9045 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 461: -#line 3091 "glslang.y" /* yacc.c:1646 */ +#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 9055 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9055 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 462: -#line 3096 "glslang.y" /* yacc.c:1646 */ +#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 9065 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9065 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 463: -#line 3101 "glslang.y" /* yacc.c:1646 */ +#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 9075 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9075 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 464: -#line 3106 "glslang.y" /* yacc.c:1646 */ +#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 9086 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9086 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 465: -#line 3112 "glslang.y" /* yacc.c:1646 */ +#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 9096 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9096 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 466: -#line 3117 "glslang.y" /* yacc.c:1646 */ +#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 9106 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9106 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 467: -#line 3122 "glslang.y" /* yacc.c:1646 */ +#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 9116 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9116 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 468: -#line 3127 "glslang.y" /* yacc.c:1646 */ +#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 9127 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9127 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 469: -#line 3133 "glslang.y" /* yacc.c:1646 */ +#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 9137 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9137 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 470: -#line 3138 "glslang.y" /* yacc.c:1646 */ +#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 9147 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9147 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 471: -#line 3143 "glslang.y" /* yacc.c:1646 */ +#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 9157 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9157 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 472: -#line 3148 "glslang.y" /* yacc.c:1646 */ +#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 9168 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9168 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 473: -#line 3154 "glslang.y" /* yacc.c:1646 */ +#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 9178 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9178 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 474: -#line 3159 "glslang.y" /* yacc.c:1646 */ +#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 9188 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9188 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 475: -#line 3164 "glslang.y" /* yacc.c:1646 */ +#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 9198 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9198 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 476: -#line 3169 "glslang.y" /* yacc.c:1646 */ +#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 9209 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9209 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 477: -#line 3175 "glslang.y" /* yacc.c:1646 */ +#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 9219 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9219 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 478: -#line 3180 "glslang.y" /* yacc.c:1646 */ +#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 9229 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9229 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 479: -#line 3185 "glslang.y" /* yacc.c:1646 */ +#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 9239 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9239 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 480: -#line 3190 "glslang.y" /* yacc.c:1646 */ +#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 9250 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9250 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 481: -#line 3196 "glslang.y" /* yacc.c:1646 */ +#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 9260 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9260 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 482: -#line 3201 "glslang.y" /* yacc.c:1646 */ +#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 9270 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9270 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 483: -#line 3206 "glslang.y" /* yacc.c:1646 */ +#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 9281 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9281 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 484: -#line 3212 "glslang.y" /* yacc.c:1646 */ +#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 9292 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9292 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 485: -#line 3218 "glslang.y" /* yacc.c:1646 */ +#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 9303 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9303 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 486: -#line 3224 "glslang.y" /* yacc.c:1646 */ +#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 9314 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9314 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 487: -#line 3230 "glslang.y" /* yacc.c:1646 */ +#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"); @@ -9322,11 +9322,11 @@ yyreduce: (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtFloat16); } -#line 9326 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9326 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 488: -#line 3237 "glslang.y" /* yacc.c:1646 */ +#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"); @@ -9334,98 +9334,98 @@ yyreduce: (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtFloat16, true); } -#line 9338 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9338 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 489: -#line 3244 "glslang.y" /* yacc.c:1646 */ +#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 9349 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9349 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 490: -#line 3250 "glslang.y" /* yacc.c:1646 */ +#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 9360 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9360 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 491: -#line 3256 "glslang.y" /* yacc.c:1646 */ +#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 9371 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9371 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 492: -#line 3262 "glslang.y" /* yacc.c:1646 */ +#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 9382 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9382 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 493: -#line 3268 "glslang.y" /* yacc.c:1646 */ +#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 9393 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9393 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 494: -#line 3274 "glslang.y" /* yacc.c:1646 */ +#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 9404 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9404 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 495: -#line 3280 "glslang.y" /* yacc.c:1646 */ +#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 9415 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9415 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 496: -#line 3287 "glslang.y" /* yacc.c:1646 */ +#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 9425 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9425 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 497: -#line 3292 "glslang.y" /* yacc.c:1646 */ +#line 3292 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // // This is for user defined type names. The lexical phase looked up the @@ -9439,47 +9439,47 @@ yyreduce: } else parseContext.error((yyvsp[0].lex).loc, "expected type name", (yyvsp[0].lex).string->c_str(), ""); } -#line 9443 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9443 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 498: -#line 3308 "glslang.y" /* yacc.c:1646 */ +#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 9453 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9453 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 499: -#line 3313 "glslang.y" /* yacc.c:1646 */ +#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 9463 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9463 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 500: -#line 3318 "glslang.y" /* yacc.c:1646 */ +#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 9473 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9473 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 501: -#line 3326 "glslang.y" /* yacc.c:1646 */ +#line 3326 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.nestedStructCheck((yyvsp[-2].lex).loc); } -#line 9479 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9479 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 502: -#line 3326 "glslang.y" /* yacc.c:1646 */ +#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); @@ -9491,17 +9491,17 @@ yyreduce: (yyval.interm.type).userDef = structure; --parseContext.structNestingLevel; } -#line 9495 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9495 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 503: -#line 3337 "glslang.y" /* yacc.c:1646 */ +#line 3337 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.nestedStructCheck((yyvsp[-1].lex).loc); } -#line 9501 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9501 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 504: -#line 3337 "glslang.y" /* yacc.c:1646 */ +#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); @@ -9509,19 +9509,19 @@ yyreduce: (yyval.interm.type).userDef = structure; --parseContext.structNestingLevel; } -#line 9513 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9513 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 505: -#line 3347 "glslang.y" /* yacc.c:1646 */ +#line 3347 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeList) = (yyvsp[0].interm.typeList); } -#line 9521 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9521 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 506: -#line 3350 "glslang.y" /* yacc.c:1646 */ +#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) { @@ -9532,11 +9532,11 @@ yyreduce: (yyval.interm.typeList)->push_back((*(yyvsp[0].interm.typeList))[i]); } } -#line 9536 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9536 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 507: -#line 3363 "glslang.y" /* yacc.c:1646 */ +#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"); @@ -9559,11 +9559,11 @@ yyreduce: (*(yyval.interm.typeList))[i].type->shallowCopy(type); } } -#line 9563 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9563 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 508: -#line 3385 "glslang.y" /* yacc.c:1646 */ +#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"); @@ -9588,38 +9588,38 @@ yyreduce: (*(yyval.interm.typeList))[i].type->shallowCopy(type); } } -#line 9592 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9592 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 509: -#line 3412 "glslang.y" /* yacc.c:1646 */ +#line 3412 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeList) = new TTypeList; (yyval.interm.typeList)->push_back((yyvsp[0].interm.typeLine)); } -#line 9601 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9601 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 510: -#line 3416 "glslang.y" /* yacc.c:1646 */ +#line 3416 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeList)->push_back((yyvsp[0].interm.typeLine)); } -#line 9609 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9609 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 511: -#line 3422 "glslang.y" /* yacc.c:1646 */ +#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 9619 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9619 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 512: -#line 3427 "glslang.y" /* yacc.c:1646 */ +#line 3427 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.arrayOfArrayVersionCheck((yyvsp[-1].lex).loc, (yyvsp[0].interm).arraySizes); @@ -9628,235 +9628,235 @@ yyreduce: (yyval.interm.typeLine).type->setFieldName(*(yyvsp[-1].lex).string); (yyval.interm.typeLine).type->transferArraySizes((yyvsp[0].interm).arraySizes); } -#line 9632 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9632 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 513: -#line 3438 "glslang.y" /* yacc.c:1646 */ +#line 3438 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 9640 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9640 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 514: -#line 3442 "glslang.y" /* yacc.c:1646 */ +#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 9651 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9651 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 515: -#line 3448 "glslang.y" /* yacc.c:1646 */ +#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 9662 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9662 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 516: -#line 3459 "glslang.y" /* 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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9670 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 517: -#line 3462 "glslang.y" /* 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 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9678 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 518: -#line 3469 "glslang.y" /* yacc.c:1646 */ +#line 3469 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9684 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9684 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 519: -#line 3473 "glslang.y" /* yacc.c:1646 */ +#line 3473 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9690 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9690 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 520: -#line 3474 "glslang.y" /* yacc.c:1646 */ +#line 3474 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9696 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9696 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 521: -#line 3480 "glslang.y" /* yacc.c:1646 */ +#line 3480 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9702 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9702 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 522: -#line 3481 "glslang.y" /* yacc.c:1646 */ +#line 3481 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9708 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9708 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 523: -#line 3482 "glslang.y" /* yacc.c:1646 */ +#line 3482 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9714 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9714 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 524: -#line 3483 "glslang.y" /* yacc.c:1646 */ +#line 3483 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9720 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9720 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 525: -#line 3484 "glslang.y" /* yacc.c:1646 */ +#line 3484 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9726 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9726 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 526: -#line 3485 "glslang.y" /* yacc.c:1646 */ +#line 3485 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9732 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9732 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 527: -#line 3486 "glslang.y" /* yacc.c:1646 */ +#line 3486 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9738 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9738 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 528: -#line 3488 "glslang.y" /* yacc.c:1646 */ +#line 3488 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9744 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9744 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 529: -#line 3494 "glslang.y" /* yacc.c:1646 */ +#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 9754 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9754 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 530: -#line 3503 "glslang.y" /* yacc.c:1646 */ +#line 3503 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; } -#line 9760 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9760 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 531: -#line 3504 "glslang.y" /* yacc.c:1646 */ +#line 3504 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.symbolTable.push(); ++parseContext.statementNestingLevel; } -#line 9769 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9769 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 532: -#line 3508 "glslang.y" /* yacc.c:1646 */ +#line 3508 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); --parseContext.statementNestingLevel; } -#line 9778 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9778 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 533: -#line 3512 "glslang.y" /* yacc.c:1646 */ +#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 9788 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9788 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 534: -#line 3520 "glslang.y" /* yacc.c:1646 */ +#line 3520 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9794 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9794 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 535: -#line 3521 "glslang.y" /* yacc.c:1646 */ +#line 3521 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9800 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9800 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 536: -#line 3525 "glslang.y" /* yacc.c:1646 */ +#line 3525 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { ++parseContext.controlFlowNestingLevel; } -#line 9808 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9808 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 537: -#line 3528 "glslang.y" /* yacc.c:1646 */ +#line 3528 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { --parseContext.controlFlowNestingLevel; (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9817 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9817 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 538: -#line 3532 "glslang.y" /* yacc.c:1646 */ +#line 3532 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.symbolTable.push(); ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 9827 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9827 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 539: -#line 3537 "glslang.y" /* yacc.c:1646 */ +#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 9838 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9838 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 540: -#line 3546 "glslang.y" /* yacc.c:1646 */ +#line 3546 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; } -#line 9846 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9846 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 541: -#line 3549 "glslang.y" /* yacc.c:1646 */ +#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 9856 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9856 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 542: -#line 3557 "glslang.y" /* yacc.c:1646 */ +#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 || @@ -9865,11 +9865,11 @@ yyreduce: (yyval.interm.intermNode) = 0; // start a fresh subsequence for what's after this case } } -#line 9869 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9869 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 543: -#line 3565 "glslang.y" /* yacc.c:1646 */ +#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)) { @@ -9878,76 +9878,76 @@ yyreduce: } else (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-1].interm.intermNode), (yyvsp[0].interm.intermNode)); } -#line 9882 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9882 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 544: -#line 3576 "glslang.y" /* yacc.c:1646 */ +#line 3576 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; } -#line 9888 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9888 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 545: -#line 3577 "glslang.y" /* yacc.c:1646 */ +#line 3577 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = static_cast((yyvsp[-1].interm.intermTypedNode)); } -#line 9894 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9894 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 546: -#line 3581 "glslang.y" /* yacc.c:1646 */ +#line 3581 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9902 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9902 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 547: -#line 3585 "glslang.y" /* yacc.c:1646 */ +#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 9911 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9911 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 548: -#line 3592 "glslang.y" /* yacc.c:1646 */ +#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 9920 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9920 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 549: -#line 3599 "glslang.y" /* yacc.c:1646 */ +#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 9929 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9929 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 550: -#line 3603 "glslang.y" /* yacc.c:1646 */ +#line 3603 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.nodePair).node1 = (yyvsp[0].interm.intermNode); (yyval.interm.nodePair).node2 = 0; } -#line 9938 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9938 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 551: -#line 3611 "glslang.y" /* yacc.c:1646 */ +#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 9947 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9947 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 552: -#line 3615 "glslang.y" /* yacc.c:1646 */ +#line 3615 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.boolCheck((yyvsp[-2].lex).loc, (yyvsp[-3].interm.type)); @@ -9958,28 +9958,28 @@ yyreduce: else (yyval.interm.intermTypedNode) = 0; } -#line 9962 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9962 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 553: -#line 3628 "glslang.y" /* yacc.c:1646 */ +#line 3628 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9970 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9970 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 554: -#line 3632 "glslang.y" /* yacc.c:1646 */ +#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 9979 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9979 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 555: -#line 3639 "glslang.y" /* yacc.c:1646 */ +#line 3639 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // start new switch sequence on the switch stack ++parseContext.controlFlowNestingLevel; @@ -9988,11 +9988,11 @@ yyreduce: parseContext.switchLevel.push_back(parseContext.statementNestingLevel); parseContext.symbolTable.push(); } -#line 9992 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 9992 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 556: -#line 3647 "glslang.y" /* yacc.c:1646 */ +#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(); @@ -10002,27 +10002,27 @@ yyreduce: --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 10006 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10006 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 557: -#line 3659 "glslang.y" /* yacc.c:1646 */ +#line 3659 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; } -#line 10014 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10014 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 558: -#line 3662 "glslang.y" /* yacc.c:1646 */ +#line 3662 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 10022 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10022 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 559: -#line 3668 "glslang.y" /* yacc.c:1646 */ +#line 3668 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; if (parseContext.switchLevel.size() == 0) @@ -10035,11 +10035,11 @@ yyreduce: (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpCase, (yyvsp[-1].interm.intermTypedNode), (yyvsp[-2].lex).loc); } } -#line 10039 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10039 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 560: -#line 3680 "glslang.y" /* yacc.c:1646 */ +#line 3680 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; if (parseContext.switchLevel.size() == 0) @@ -10049,28 +10049,28 @@ yyreduce: else (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpDefault, (yyvsp[-1].lex).loc); } -#line 10053 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10053 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 561: -#line 3692 "glslang.y" /* yacc.c:1646 */ +#line 3692 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 10061 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10061 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 562: -#line 3696 "glslang.y" /* yacc.c:1646 */ +#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 10070 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10070 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 563: -#line 3703 "glslang.y" /* yacc.c:1646 */ +#line 3703 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if (! parseContext.limits.whileLoops) parseContext.error((yyvsp[-1].lex).loc, "while loops not available", "limitation", ""); @@ -10079,11 +10079,11 @@ yyreduce: ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 10083 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10083 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 564: -#line 3711 "glslang.y" /* yacc.c:1646 */ +#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); @@ -10091,21 +10091,21 @@ yyreduce: --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 10095 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10095 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 565: -#line 3718 "glslang.y" /* yacc.c:1646 */ +#line 3718 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { ++parseContext.loopNestingLevel; ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 10105 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10105 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 566: -#line 3723 "glslang.y" /* yacc.c:1646 */ +#line 3723 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if (! parseContext.limits.whileLoops) parseContext.error((yyvsp[-7].lex).loc, "do-while loops not available", "limitation", ""); @@ -10117,22 +10117,22 @@ yyreduce: --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 10121 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10121 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 567: -#line 3734 "glslang.y" /* yacc.c:1646 */ +#line 3734 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 10132 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10132 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 568: -#line 3740 "glslang.y" /* yacc.c:1646 */ +#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); @@ -10145,81 +10145,81 @@ yyreduce: --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 10149 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10149 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 569: -#line 3755 "glslang.y" /* yacc.c:1646 */ +#line 3755 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 10157 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10157 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 570: -#line 3758 "glslang.y" /* yacc.c:1646 */ +#line 3758 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 10165 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10165 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 571: -#line 3764 "glslang.y" /* yacc.c:1646 */ +#line 3764 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 10173 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10173 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 572: -#line 3767 "glslang.y" /* yacc.c:1646 */ +#line 3767 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = 0; } -#line 10181 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10181 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 573: -#line 3773 "glslang.y" /* yacc.c:1646 */ +#line 3773 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.nodePair).node1 = (yyvsp[-1].interm.intermTypedNode); (yyval.interm.nodePair).node2 = 0; } -#line 10190 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10190 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 574: -#line 3777 "glslang.y" /* yacc.c:1646 */ +#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 10199 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10199 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 575: -#line 3784 "glslang.y" /* yacc.c:1646 */ +#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 10209 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10209 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 576: -#line 3789 "glslang.y" /* yacc.c:1646 */ +#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 10219 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10219 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 577: -#line 3794 "glslang.y" /* yacc.c:1646 */ +#line 3794 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpReturn, (yyvsp[-1].lex).loc); if (parseContext.currentFunctionType->getBasicType() != EbtVoid) @@ -10227,83 +10227,91 @@ yyreduce: if (parseContext.inMain) parseContext.postEntryPointReturn = true; } -#line 10231 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10231 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 578: -#line 3801 "glslang.y" /* yacc.c:1646 */ +#line 3801 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = parseContext.handleReturnValue((yyvsp[-2].lex).loc, (yyvsp[-1].interm.intermTypedNode)); } -#line 10239 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10239 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 579: -#line 3804 "glslang.y" /* yacc.c:1646 */ +#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 10248 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10248 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 580: -#line 3813 "glslang.y" /* yacc.c:1646 */ +#line 3813 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); parseContext.intermediate.setTreeRoot((yyval.interm.intermNode)); } -#line 10257 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10257 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 581: -#line 3817 "glslang.y" /* yacc.c:1646 */ +#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 10268 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10268 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 582: -#line 3826 "glslang.y" /* yacc.c:1646 */ +#line 3826 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 10276 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10276 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 583: -#line 3829 "glslang.y" /* yacc.c:1646 */ +#line 3829 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 10284 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10284 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 584: -#line 3833 "glslang.y" /* yacc.c:1646 */ +#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 10294 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10294 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 585: -#line 3842 "glslang.y" /* yacc.c:1646 */ +#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 10303 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10311 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 586: -#line 3846 "glslang.y" /* yacc.c:1646 */ +#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) @@ -10318,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 10323 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10342 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 587: -#line 3865 "glslang.y" /* yacc.c:1646 */ +#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 10332 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10351 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 588: -#line 3871 "glslang.y" /* yacc.c:1646 */ +#line 3890 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.attributes) = (yyvsp[0].interm.attributes); } -#line 10340 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10359 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 589: -#line 3874 "glslang.y" /* yacc.c:1646 */ +#line 3893 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.attributes) = parseContext.mergeAttributes((yyvsp[-2].interm.attributes), (yyvsp[0].interm.attributes)); } -#line 10348 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10367 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 590: -#line 3879 "glslang.y" /* yacc.c:1646 */ +#line 3898 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.attributes) = parseContext.makeAttributes(*(yyvsp[0].lex).string); } -#line 10356 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10375 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 591: -#line 3882 "glslang.y" /* yacc.c:1646 */ +#line 3901 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.attributes) = parseContext.makeAttributes(*(yyvsp[-3].lex).string, (yyvsp[-1].interm.intermTypedNode)); } -#line 10364 "glslang_tab.cpp" /* yacc.c:1646 */ +#line 10383 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; -#line 10368 "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 @@ -10592,6 +10611,5 @@ yyreturn: #endif return yyresult; } -#line 3887 "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 31c8f9024..78b72a246 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp.h +++ b/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp.h @@ -30,8 +30,8 @@ This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ -#ifndef YY_YY_GLSLANG_TAB_CPP_H_INCLUDED -# define YY_YY_GLSLANG_TAB_CPP_H_INCLUDED +#ifndef YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED +# define YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 1 @@ -470,7 +470,7 @@ extern int yydebug; union YYSTYPE { -#line 97 "glslang.y" /* yacc.c:1909 */ +#line 97 "MachineIndependent/glslang.y" /* yacc.c:1909 */ struct { glslang::TSourceLoc loc; @@ -506,7 +506,7 @@ union YYSTYPE glslang::TArraySizes* typeParameters; } interm; -#line 510 "glslang_tab.cpp.h" /* yacc.c:1909 */ +#line 510 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */ }; typedef union YYSTYPE YYSTYPE; @@ -518,4 +518,4 @@ typedef union YYSTYPE YYSTYPE; int yyparse (glslang::TParseContext* pParseContext); -#endif /* !YY_YY_GLSLANG_TAB_CPP_H_INCLUDED */ +#endif /* !YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED */ diff --git a/src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp b/src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp index 86edcfe4d..f23a7058a 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp @@ -36,7 +36,7 @@ // POSSIBILITY OF SUCH DAMAGE. // -#ifndef GLSLANG_WEB +#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) #include "localintermediate.h" #include "../Include/InfoSink.h" @@ -1466,7 +1466,7 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree) infoSink.debug << "Shader version: " << version << "\n"; if (requestedExtensions.size() > 0) { for (auto extIt = requestedExtensions.begin(); extIt != requestedExtensions.end(); ++extIt) - infoSink.debug << "Requested " << extIt->first << "\n"; + infoSink.debug << "Requested " << *extIt << "\n"; } if (xfbMode) @@ -1562,4 +1562,4 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree) } // end namespace glslang -#endif // not GLSLANG_WEB +#endif // !GLSLANG_WEB && !GLSLANG_ANGLE diff --git a/src/libraries/glslang/glslang/MachineIndependent/iomapper.cpp b/src/libraries/glslang/glslang/MachineIndependent/iomapper.cpp index fadcb1bf9..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(); @@ -1105,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); }); @@ -1200,11 +1206,12 @@ bool TGlslIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TIn *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, @@ -1281,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 7ca18b8a5..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 @@ -186,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; // @@ -299,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 96ea46876..a8e031bc6 100755 --- 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; @@ -533,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 @@ -1362,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); } diff --git a/src/libraries/glslang/glslang/MachineIndependent/localintermediate.h b/src/libraries/glslang/glslang/MachineIndependent/localintermediate.h index a3ff88683..3cdc1f10c 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/localintermediate.h +++ b/src/libraries/glslang/glslang/MachineIndependent/localintermediate.h @@ -233,6 +233,31 @@ 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. @@ -241,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), @@ -295,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) { @@ -357,15 +396,8 @@ public: } const SpvVersion& getSpv() const { return spvVersion; } EShLanguage getStage() const { return language; } - void updateRequestedExtension(const char* extension, TExtensionBehavior behavior) { - if(requestedExtensions.find(extension) != requestedExtensions.end()) { - requestedExtensions[extension] = behavior; - } else { - requestedExtensions.insert(std::make_pair(extension, behavior)); - } - } - - const std::map& getRequestedExtensions() const { return requestedExtensions; } + void addRequestedExtension(const char* extension) { requestedExtensions.insert(extension); } + const std::set& getRequestedExtensions() const { return requestedExtensions; } void setTreeRoot(TIntermNode* r) { treeRoot = r; } TIntermNode* getTreeRoot() const { return treeRoot; } @@ -411,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; @@ -433,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&); @@ -462,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); @@ -480,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; } @@ -856,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: @@ -903,23 +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 { - auto it = requestedExtensions.find(extension); - if (it != requestedExtensions.end()) { - return (it->second == EBhDisable) ? false : true; - } - return false; - } -#endif + std::tuple getConversionDestinationType(TBasicType type0, TBasicType type1, TOperator op) const; static const char* getResourceName(TResourceType); @@ -929,11 +945,16 @@ 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::map requestedExtensions; // cumulation of all enabled or required extensions; not connected to what subset of the shader used them + std::set requestedExtensions; // cumulation of all enabled or required extensions; not connected to what subset of the shader used them TBuiltInResource resources; int numEntryPoints; int numErrors; @@ -1004,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/parseVersions.h b/src/libraries/glslang/glslang/MachineIndependent/parseVersions.h index 0d006a716..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 @@ -116,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, @@ -224,7 +229,7 @@ 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 diff --git a/src/libraries/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp b/src/libraries/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp index ec3935614..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); @@ -1184,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; @@ -1285,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/reflection.cpp b/src/libraries/glslang/glslang/MachineIndependent/reflection.cpp index d394cf01f..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" @@ -639,11 +639,11 @@ public: int addBlockName(const TString& name, const TType& type, int size) { - int blockIndex; + int blockIndex = 0; if (type.isArray()) { TType derefType(type, 0); for (int e = 0; e < type.getOuterArraySize(); ++e) { - uint32_t memberBlockIndex = addBlockName(name + "[" + String(e) + "]", derefType, size); + int memberBlockIndex = addBlockName(name + "[" + String(e) + "]", derefType, size); if (e == 0) blockIndex = memberBlockIndex; } @@ -1266,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 0c33de459..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 +#endif // !GLSLANG_WEB && !GLSLANG_ANGLE diff --git a/src/libraries/glslang/glslang/Public/ShaderLang.h b/src/libraries/glslang/glslang/Public/ShaderLang.h index 7905b3d16..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 14 - // // 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. @@ -205,7 +209,7 @@ struct TEnvironment { TTarget target; // what to generate }; -const char* StageName(EShLanguage); +GLSLANG_EXPORT const char* StageName(EShLanguage); } // end namespace glslang @@ -306,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 @@ -318,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, @@ -331,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); @@ -340,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" @@ -390,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 { @@ -435,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 @@ -608,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) @@ -632,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; } @@ -674,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. @@ -683,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; @@ -792,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() @@ -802,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 @@ -902,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/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 diff --git a/src/love.cpp b/src/love.cpp index 79cfd2050..553393bdc 100644 --- a/src/love.cpp +++ b/src/love.cpp @@ -76,38 +76,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_MACOS - // 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::macos::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_MACOS) - loveResourcesPath = love::macos::getLoveInResources(); + loveResourcesPath = love::macos::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_MACOS + 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::macos::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(); 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; 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 &renderers) return instance; } +Graphics::DisplayState::DisplayState() +{ + defaultSamplerState.mipmapFilter = SamplerState::MIPMAP_FILTER_LINEAR; +} + Graphics::Graphics() : width(0) , height(0) @@ -202,7 +207,7 @@ void Graphics::createQuadIndexBuffer() size_t size = sizeof(uint16) * (LOVE_UINT16_MAX / 4) * 6; - Buffer::Settings settings(Buffer::TYPEFLAG_INDEX, 0, BUFFERUSAGE_STATIC); + Buffer::Settings settings(Buffer::TYPEFLAG_INDEX, BUFFERUSAGE_STATIC); quadIndexBuffer = newBuffer(settings, DATAFORMAT_UINT16, nullptr, size, 0); Buffer::Mapper map(*quadIndexBuffer); diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index 541921104..15e52d5b7 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -472,7 +472,7 @@ public: * @param width The viewport width. * @param height The viewport height. **/ - virtual bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, int backbufferdepth) = 0; + virtual bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) = 0; /** * Un-sets the current graphics display mode (uninitializing objects if @@ -507,6 +507,9 @@ public: double getCurrentDPIScale() const; double getScreenDPIScale() const; + virtual int getRequestedBackbufferMSAA() const = 0; + virtual int getBackbufferMSAA() const = 0; + /** * Sets the current constant color. **/ @@ -874,6 +877,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); @@ -905,6 +910,7 @@ protected: bool wireframe = false; + // Default mipmap filter is set in the DisplayState constructor. SamplerState defaultSamplerState = SamplerState(); }; diff --git a/src/modules/graphics/Mesh.cpp b/src/modules/graphics/Mesh.cpp index c85662a08..46b425394 100644 --- a/src/modules/graphics/Mesh.cpp +++ b/src/modules/graphics/Mesh.cpp @@ -46,20 +46,21 @@ 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 677f69352..6fd5eaefb 100644 --- a/src/modules/graphics/SpriteBatch.cpp +++ b/src/modules/graphics/SpriteBatch.cpp @@ -47,6 +47,8 @@ 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_sprites() , range_start(-1) , range_count(-1) { @@ -64,14 +66,22 @@ SpriteBatch::SpriteBatch(Graphics *gfx, Texture *texture, int size, BufferUsage vertex_stride = getFormatStride(vertex_format); size_t vertex_size = vertex_stride * 4 * size; - Buffer::Settings settings(Buffer::TYPEFLAG_VERTEX, Buffer::MAP_EXPLICIT_RANGE_MODIFY, usage); + + 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, 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 +103,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 +117,7 @@ int SpriteBatch::add(Quad *quad, const Matrix4 &m, int index /*= -1*/) verts[i].color = color; } - array_buf->setMappedRangeModified(offset, vertex_stride * 4); + modified_sprites.encapsulate(spriteindex); // Increment counter. if (index == -1) @@ -137,9 +148,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 +163,7 @@ int SpriteBatch::addLayer(int layer, Quad *quad, const Matrix4 &m, int index) verts[i].color = color; } - array_buf->setMappedRangeModified(offset, vertex_stride * 4); + modified_sprites.encapsulate(spriteindex); // Increment counter. if (index == -1) @@ -168,7 +180,18 @@ void SpriteBatch::clear() void SpriteBatch::flush() { - array_buf->unmap(); + if (modified_sprites.isValid()) + { + size_t offset = modified_sprites.getOffset() * vertex_stride * 4; + size_t size = modified_sprites.getSize() * vertex_stride * 4; + + if (array_buf->getUsage() == BUFFERUSAGE_STREAM) + array_buf->fill(0, array_buf->getSize(), vertex_data); + else + array_buf->fill(offset, size, vertex_data + offset); + + modified_sprites.invalidate(); + } } void SpriteBatch::setTexture(Texture *newtexture) @@ -213,33 +236,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->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; } @@ -248,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."); @@ -269,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; } @@ -319,8 +334,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; @@ -353,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 40fbfd932..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; }; @@ -130,8 +135,11 @@ private: CommonFormat vertex_format; size_t vertex_stride; - - love::graphics::Buffer *array_buf; + + StrongRef array_buf; + uint8 *vertex_data; + + Range modified_sprites; std::unordered_map attached_attributes; diff --git a/src/modules/graphics/Text.cpp b/src/modules/graphics/Text.cpp index 3b3d54d57..3fa4d5ff3 100644 --- a/src/modules/graphics/Text.cpp +++ b/src/modules/graphics/Text.cpp @@ -33,17 +33,18 @@ 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) + , vertexData(nullptr) + , modifiedVertices() + , vertOffset(0) + , textureCacheID((uint32) -1) { set(text); } Text::~Text() { - if (vertex_buffer) - vertex_buffer->release(); + if (vertexData != nullptr) + free(vertexData); } void Text::uploadVertices(const std::vector &vertices, size_t vertoffset) @@ -52,33 +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->release(); - 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); } } @@ -86,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(); } @@ -196,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) @@ -213,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(); } @@ -225,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(); @@ -258,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 0e3259919..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; - Buffer *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/Texture.cpp b/src/modules/graphics/Texture.cpp index 072110b6e..3c509cf81 100644 --- a/src/modules/graphics/Texture.cpp +++ b/src/modules/graphics/Texture.cpp @@ -173,7 +173,7 @@ Texture::Texture(Graphics *gfx, 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) @@ -231,6 +231,9 @@ Texture::Texture(Graphics *gfx, 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."); @@ -279,6 +282,9 @@ Texture::Texture(Graphics *gfx, 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); @@ -485,6 +491,20 @@ 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."); + + if (isPixelFormatDepthStencil(format)) + throw love::Exception("generateMipmaps cannot be called on a depth/stencil Texture."); + + generateMipmapsInternal(); +} + love::image::ImageData *Texture::newImageData(love::image::Image *module, int slice, int mipmap, const Rect &r) { if (!isReadable()) @@ -519,7 +539,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 9db40ff6f..3fdcf29db 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/metal/Buffer.h b/src/modules/graphics/metal/Buffer.h index 2ae14accf..30899934a 100644 --- a/src/modules/graphics/metal/Buffer.h +++ b/src/modules/graphics/metal/Buffer.h @@ -22,6 +22,7 @@ #include "graphics/Buffer.h" #include "Metal.h" +#include "common/Range.h" namespace love { @@ -37,23 +38,21 @@ public: Buffer(love::graphics::Graphics *gfx, id device, const Settings &settings, const std::vector &format, const void *data, size_t size, size_t arraylength); virtual ~Buffer(); - 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 (ptrdiff_t) buffer; } ptrdiff_t getTexelBufferHandle() const override { return (ptrdiff_t) texture; } - void copyTo(size_t offset, size_t size, love::graphics::Buffer *other, size_t otheroffset) override; - private: id buffer; id texture; - char *memoryMap; + id mapBuffer; - NSRange mappedRange; + Range mappedRange; }; // Buffer diff --git a/src/modules/graphics/metal/Buffer.mm b/src/modules/graphics/metal/Buffer.mm index 440f00c17..8845f1b3e 100644 --- a/src/modules/graphics/metal/Buffer.mm +++ b/src/modules/graphics/metal/Buffer.mm @@ -19,6 +19,7 @@ **/ #import "Buffer.h" +#include "Graphics.h" namespace love { @@ -58,12 +59,13 @@ static MTLPixelFormat getMTLPixelFormat(DataFormat format) Buffer::Buffer(love::graphics::Graphics *gfx, id device, const Settings &settings, const std::vector &format, const void *data, size_t size, size_t arraylength) : love::graphics::Buffer(gfx, settings, format, size, arraylength) , texture(nil) + , mapBuffer(nil) , mappedRange() { @autoreleasepool { size = getSize(); arraylength = getArrayLength(); - MTLResourceOptions opts = MTLResourceStorageModeManaged; + MTLResourceOptions opts = MTLResourceStorageModePrivate; buffer = [device newBufferWithLength:size options:opts]; if (buffer == nil) @@ -71,25 +73,22 @@ Buffer::Buffer(love::graphics::Graphics *gfx, id device, const Settin if (typeFlags & TYPEFLAG_TEXEL) { - MTLPixelFormat pixformat = getMTLPixelFormat(getDataMember(0).decl.format); - auto desc = [MTLTextureDescriptor textureBufferDescriptorWithPixelFormat:pixformat - width:size - resourceOptions:opts - usage:MTLTextureUsageShaderRead]; - texture = [buffer newTextureWithDescriptor:desc offset:0 bytesPerRow:size]; + if (@available(iOS 12, macOS 10.14, *)) + { + MTLPixelFormat pixformat = getMTLPixelFormat(getDataMember(0).decl.format); + auto desc = [MTLTextureDescriptor textureBufferDescriptorWithPixelFormat:pixformat + width:size + resourceOptions:opts + usage:MTLTextureUsageShaderRead]; + texture = [buffer newTextureWithDescriptor:desc offset:0 bytesPerRow:size]; + } if (texture == nil) throw love::Exception("Could not create Metal texel buffer."); } - // TODO: synchronization etc - memoryMap = (char *) buffer.contents; - if (data != nullptr) - { - memcpy(map(), data, size); - unmap(); - } + fill(0, size, data); }} Buffer::~Buffer() @@ -98,30 +97,77 @@ Buffer::~Buffer() texture = nil; }} -void *Buffer::map() -{ - return memoryMap; -} - -void Buffer::unmap() +void *Buffer::map(MapType /*map*/, size_t offset, size_t size) { @autoreleasepool { - [buffer didModifyRange:{0, size}]; + if (size == 0) + return nullptr; + + Range r(offset, size); + + if (!Range(0, getSize()).contains(r)) + return nullptr; + + auto gfx = Graphics::getInstance(); + + // TODO: Don't create a new buffer every time, also do something for stream + // buffers. + mapBuffer = [gfx->device newBufferWithLength:size options:MTLResourceStorageModeShared]; + + if (mapBuffer != nil) + { + mappedRange = r; + return mapBuffer.contents; + } + + return nullptr; }} -void Buffer::setMappedRangeModified(size_t offset, size_t size) -{ - mappedRange = NSIntersectionRange(mappedRange, {offset, size}); -} +void Buffer::unmap(size_t usedoffset, size_t usedsize) +{ @autoreleasepool { + if (mapBuffer == nil) + return; + + Range r(usedoffset, usedsize); + + if (!mapped || !mappedRange.contains(r)) + return; + + auto gfx = Graphics::getInstance(); + auto encoder = gfx->useBlitEncoder(); + + [encoder copyFromBuffer:mapBuffer + sourceOffset:(usedoffset - mappedRange.getOffset()) + toBuffer:buffer + destinationOffset:usedoffset + size:usedsize]; + + mapBuffer = nil; +}} void Buffer::fill(size_t offset, size_t size, const void *data) -{ - // TODO -} +{ @autoreleasepool { + if (size == 0) + return; -void Buffer::copyTo(size_t offset, size_t size, love::graphics::Buffer *other, size_t otheroffset) -{ - // TODO -} + size_t buffersize = getSize(); + + if (!Range(0, buffersize).contains(Range(offset, size))) + return; + + // TODO: Don't create a new buffer every time, also do something for stream + // buffers. + auto gfx = Graphics::getInstance(); + auto encoder = gfx->useBlitEncoder(); + + auto tempbuffer = [gfx->device newBufferWithLength:size options:MTLResourceStorageModeShared]; + memcpy(tempbuffer.contents, data, size); + + [encoder copyFromBuffer:tempbuffer + sourceOffset:0 + toBuffer:buffer + destinationOffset:offset + size:size]; +}} } // metal } // graphics diff --git a/src/modules/graphics/metal/Graphics.h b/src/modules/graphics/metal/Graphics.h index 898936c52..577b2b25e 100644 --- a/src/modules/graphics/metal/Graphics.h +++ b/src/modules/graphics/metal/Graphics.h @@ -49,7 +49,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(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, int backbufferdepth) override; + bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) override; void unSetMode() override; void setActive(bool active) override; @@ -65,6 +65,9 @@ public: void present(void *screenshotCallbackData) override; + int getRequestedBackbufferMSAA() const override { return 0; } // TODO + int getBackbufferMSAA() const override { return 0; } // TODO + void setColor(Colorf c) override; void setScissor(const Rect &rect) override; diff --git a/src/modules/graphics/metal/Graphics.mm b/src/modules/graphics/metal/Graphics.mm index f74794b89..a2211fc31 100644 --- a/src/modules/graphics/metal/Graphics.mm +++ b/src/modules/graphics/metal/Graphics.mm @@ -188,7 +188,8 @@ Graphics::Graphics() {0.0f, 0.0f, 0.0f, 1.0f}, {0, 0, 0, 1}, }; - Buffer::Settings attribsettings(Buffer::TYPEFLAG_VERTEX, 0, BUFFERUSAGE_STATIC); + + Buffer::Settings attribsettings(Buffer::TYPEFLAG_VERTEX, BUFFERUSAGE_STATIC); defaultAttributesBuffer = newBuffer(attribsettings, dataformat, &defaults, sizeof(DefaultVertexAttributes), 0); } @@ -288,13 +289,13 @@ void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelh } } -bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, int backbufferdepth) +bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) { @autoreleasepool { this->width = width; this->height = height; this->metalLayer = (__bridge CAMetalLayer *) context; - this->windowHasStencil = backbufferstencil; + this->windowHasStencil = windowhasstencil; metalLayer.device = device; metalLayer.pixelFormat = isGammaCorrect() ? MTLPixelFormatBGRA8Unorm_sRGB : MTLPixelFormatBGRA8Unorm; diff --git a/src/modules/graphics/metal/Texture.h b/src/modules/graphics/metal/Texture.h index 7e7ac1438..02af08220 100644 --- a/src/modules/graphics/metal/Texture.h +++ b/src/modules/graphics/metal/Texture.h @@ -40,8 +40,6 @@ public: Texture(love::graphics::Graphics *gfx, id device, const Settings &settings, const Slices *data); virtual ~Texture(); - 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 { return (ptrdiff_t) texture; } @@ -54,6 +52,8 @@ public: 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; id texture; id msaaTexture; diff --git a/src/modules/graphics/metal/Texture.mm b/src/modules/graphics/metal/Texture.mm index 2d2e484d1..3b9a1208b 100644 --- a/src/modules/graphics/metal/Texture.mm +++ b/src/modules/graphics/metal/Texture.mm @@ -197,7 +197,7 @@ void Texture::uploadByteData(PixelFormat pixelformat, const void *data, size_t s options:options]; }} -void Texture::generateMipmaps() +void Texture::generateMipmapsInternal() { @autoreleasepool { // TODO: alternate method for non-color-renderable and non-filterable // pixel formats. @@ -205,10 +205,9 @@ void Texture::generateMipmaps() [encoder generateMipmapsForTexture:texture]; }} -love::image::ImageData *Texture::newImageData(love::image::Image *module, int slice, int mipmap, const Rect &rect) +void Texture::readbackImageData(love::image::ImageData *imagedata, int slice, int mipmap, const Rect &rect) { // TODO - return nullptr; } void Texture::setSamplerState(const SamplerState &s) 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 161893bc5..f75e92b20 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -107,11 +107,24 @@ love::graphics::Graphics *createInstance() Graphics::Graphics() : windowHasStencil(false) , 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,21 +134,22 @@ 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); void *context = nullptr; // TODO - setMode(context, (int) dpiW, (int) dpiH, window->getPixelWidth(), window->getPixelHeight(), settings.stencil, settings.depth); + setMode(context, (int) dpiW, (int) dpiH, window->getPixelWidth(), window->getPixelHeight(), s.stencil, s.msaa); } } } Graphics::~Graphics() { + delete[] bufferMapMemory; } const char *Graphics::getName() const @@ -188,14 +202,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(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, int /*backbufferdepth*/) +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_RGBA8_UNORM_sRGB : 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(void */*context*/, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) { this->width = width; this->height = height; - this->windowHasStencil = backbufferstencil; + this->windowHasStencil = windowhasstencil; + this->requestedBackbufferMSAA = msaa; // Okay, setup OpenGL. gl.initContext(); @@ -211,8 +305,6 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int created = true; initCapabilities(); - setViewportSize(width, height, pixelwidth, pixelheight); - // Enable blending gl.setEnableState(OpenGL::ENABLE_BLEND, true); @@ -252,6 +344,8 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int setDebug(isDebugEnabled()); + setViewportSize(width, height, pixelwidth, pixelheight); + if (batchedDrawState.vb[0] == nullptr) { // Initial sizes that should be good enough for most cases. It will @@ -263,7 +357,7 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int 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}; @@ -335,6 +429,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(); @@ -552,7 +649,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. @@ -594,6 +691,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. @@ -646,15 +745,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) @@ -812,7 +908,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); @@ -879,7 +975,7 @@ void Graphics::cleanupRenderTexture(love::graphics::Texture *texture) } } -void Graphics::bindCachedFBO(const RenderTargets &targets) +GLuint Graphics::bindCachedFBO(const RenderTargets &targets) { GLuint fbo = framebufferObjects[targets]; @@ -962,6 +1058,8 @@ void Graphics::bindCachedFBO(const RenderTargets &targets) framebufferObjects[targets] = fbo; } + + return fbo; } void Graphics::present(void *screenshotCallbackData) @@ -977,13 +1075,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; @@ -1002,26 +1121,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_ALL, getSystemBackbufferFBO()); glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels); // Replace alpha values with full opacity. @@ -1085,6 +1185,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; @@ -1105,6 +1207,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(); @@ -1354,6 +1466,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 RENDERER_OPENGL; diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index 96eebeedf..df28518ad 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(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, int backbufferdepth) override; + bool setMode(void *context, 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; @@ -110,6 +113,9 @@ public: // Internal use. void cleanupRenderTexture(love::graphics::Texture *texture); + void *getBufferMapMemory(size_t size); + void releaseBufferMapMemory(void *mem); + private: struct CachedFBOHasher @@ -139,15 +145,27 @@ 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; + + 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 7d6cd9630..0a6c9804c 100644 --- a/src/modules/graphics/opengl/Shader.cpp +++ b/src/modules/graphics/opengl/Shader.cpp @@ -752,30 +752,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; @@ -907,13 +885,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 5bbcf2c30..a396db2e4 100644 --- a/src/modules/graphics/opengl/Shader.h +++ b/src/modules/graphics/opengl/Shader.h @@ -116,8 +116,6 @@ private: std::vector> pendingUniformUpdates; - std::vector buffersToUnmap; - float lastPointSize; }; // Shader diff --git a/src/modules/graphics/opengl/StreamBuffer.cpp b/src/modules/graphics/opengl/StreamBuffer.cpp index 966fa2a1f..672b3f3df 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 { diff --git a/src/modules/graphics/opengl/Texture.cpp b/src/modules/graphics/opengl/Texture.cpp index 756d4c43d..362e5a2a5 100644 --- a/src/modules/graphics/opengl/Texture.cpp +++ b/src/modules/graphics/opengl/Texture.cpp @@ -218,6 +218,10 @@ Texture::Texture(love::graphics::Graphics *gfx, const Settings &settings, const 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() @@ -480,14 +484,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 +496,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 +520,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 a63723552..1367ccebe 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; 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 1eb40c13e..9db224f5d 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; } 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/physics/box2d/Body.cpp b/src/modules/physics/box2d/Body.cpp index 8fadaa11f..dfdddf1ec 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.pointer = (uintptr_t)udata; body = world->world->CreateBody(&def); // Box2D body holds a reference to the love Body. this->retain(); @@ -385,9 +385,9 @@ void Body::setBullet(bool bullet) return body->SetBullet(bullet); } -bool Body::isActive() const +bool Body::isEnabled() const { - return body->IsActive(); + return body->IsEnabled(); } bool Body::isAwake() const @@ -405,9 +405,9 @@ bool Body::isSleepingAllowed() const return body->IsSleepingAllowed(); } -void Body::setActive(bool active) +void Body::setEnabled(bool enabled) { - body->SetActive(active); + body->SetEnabled(enabled); } void Body::setAwake(bool awake) @@ -544,7 +544,7 @@ int Body::setUserData(lua_State *L) if (udata == nullptr) { udata = new bodyudata(); - body->SetUserData((void *) udata); + body->GetUserData().pointer = (uintptr_t)udata; } if(!udata->ref) diff --git a/src/modules/physics/box2d/Body.h b/src/modules/physics/box2d/Body.h index f4fc1f22c..a7b2010de 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 { @@ -360,7 +360,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 @@ -377,7 +377,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 7b04c61a1..114e40beb 100644 --- a/src/modules/physics/box2d/ChainShape.cpp +++ b/src/modules/physics/box2d/ChainShape.cpp @@ -47,56 +47,28 @@ void ChainShape::setNextVertex(float x, float y) { b2Vec2 v(x, y); b2ChainShape *c = (b2ChainShape *)shape; - c->SetNextVertex(Physics::scaleDown(v)); -} - -void ChainShape::setNextVertex() -{ - b2ChainShape *c = (b2ChainShape *)shape; - c->m_hasNextVertex = false; + c->m_nextVertex = Physics::scaleDown(v); } 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 +b2Vec2 ChainShape::getNextVertex() 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; + return Physics::scaleUp(c->m_nextVertex); } -bool ChainShape::getPreviousVertex(float &x, float &y) const +b2Vec2 ChainShape::getPreviousVertex() 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; + 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 06c192be1..3afbc7365 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; + b2Vec2 getNextVertex() const; /** * Gets the vertex that precedes the first vertex. **/ - bool getPreviousVertex(float &x, float &y) const; + b2Vec2 getPreviousVertex() const; /** * Returns a child EdgeShape. 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/DistanceJoint.cpp b/src/modules/physics/box2d/DistanceJoint.cpp index 3e7c27597..892ff34fd 100644 --- a/src/modules/physics/box2d/DistanceJoint.cpp +++ b/src/modules/physics/box2d/DistanceJoint.cpp @@ -58,22 +58,50 @@ float DistanceJoint::getLength() const void DistanceJoint::setFrequency(float hz) { - joint->SetFrequency(hz); + float stiffness, damping; + b2LinearStiffness(stiffness, damping, hz, getDampingRatio(), joint->GetBodyA(), joint->GetBodyB()); + joint->SetStiffness(stiffness); } float DistanceJoint::getFrequency() const { - return joint->GetFrequency(); + float frequency, ratio; + Physics::b2LinearFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB()); + return frequency; } -void DistanceJoint::setDampingRatio(float d) +void DistanceJoint::setDampingRatio(float ratio) { - joint->SetDampingRatio(d); + float stiffness, damping; + b2LinearStiffness(stiffness, damping, getFrequency(), ratio, joint->GetBodyA(), joint->GetBodyB()); + joint->SetDamping(damping); } float DistanceJoint::getDampingRatio() const { - return joint->GetDampingRatio(); + 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 +{ + return joint->GetStiffness(); +} + +void DistanceJoint::setDamping(float d) +{ + joint->SetDamping(d); +} + +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..45cb0a613 100644 --- a/src/modules/physics/box2d/DistanceJoint.h +++ b/src/modules/physics/box2d/DistanceJoint.h @@ -57,27 +57,45 @@ public: float getLength() const; /** - * Sets the response speed. + * Sets the response speed. Independent of mass **/ void setFrequency(float hz); /** - * Gets the response speed. + * Gets the response speed. Independent of mass **/ float getFrequency() const; /** - * Sets the damping ratio. - * 0 = no damping, 1 = critical damping. + * Set the spring damping ratio. Independent of mass **/ - void setDampingRatio(float d); + void setDampingRatio(float ratio); /** - * Gets the damping ratio. - * 0 = no damping, 1 = critical damping. + * 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. Dependent of mass + **/ + void setDamping(float ratio); + + /** + * Get the spring damping. Dependent of mass + **/ + float getDamping() const; + private: // The Box2D DistanceJoint object. b2DistanceJoint *joint; diff --git a/src/modules/physics/box2d/EdgeShape.cpp b/src/modules/physics/box2d/EdgeShape.cpp index ebe1d0423..aad7a36e2 100644 --- a/src/modules/physics/box2d/EdgeShape.cpp +++ b/src/modules/physics/box2d/EdgeShape.cpp @@ -48,28 +48,13 @@ 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 +b2Vec2 EdgeShape::getNextVertex() 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; + return Physics::scaleUp(e->m_vertex3); } void EdgeShape::setPreviousVertex(float x, float y) @@ -77,28 +62,13 @@ 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 +b2Vec2 EdgeShape::getPreviousVertex() 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; + 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 0eb814eac..ac15b940b 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; + b2Vec2 getNextVertex() const; void setPreviousVertex(float x, float y); - void setPreviousVertex(); - bool getPreviousVertex(float &x, float &y) const; + b2Vec2 getPreviousVertex() const; /** * Returns the transformed points of the edge shape. diff --git a/src/modules/physics/box2d/Fixture.cpp b/src/modules/physics/box2d/Fixture.cpp index 6278eb45f..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 = (void *)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((void *) udata); + fixture->GetUserData().pointer = (uintptr_t)udata; } if(!udata->ref) 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.cpp b/src/modules/physics/box2d/Joint.cpp index e73ee84d4..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. @@ -185,9 +185,9 @@ void Joint::destroyJoint(bool implicit) this->release(); } -bool Joint::isActive() const +bool Joint::isEnabled() const { - return joint->IsActive(); + return joint->IsEnabled(); } bool Joint::getCollideConnected() const @@ -202,7 +202,7 @@ int Joint::setUserData(lua_State *L) if (udata == nullptr) { udata = new jointudata(); - joint->SetUserData((void *) udata); + joint->GetUserData().pointer = (uintptr_t)udata; } if(!udata->ref) diff --git a/src/modules/physics/box2d/Joint.h b/src/modules/physics/box2d/Joint.h index 094c54b2c..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 { @@ -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 f9ae91745..4475dd53d 100644 --- a/src/modules/physics/box2d/MouseJoint.cpp +++ b/src/modules/physics/box2d/MouseJoint.cpp @@ -80,28 +80,62 @@ float MouseJoint::getMaxForce() const void MouseJoint::setFrequency(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->SetFrequency(hz); + float stiffness, damping; + b2LinearStiffness(stiffness, damping, hz, getDampingRatio(), joint->GetBodyA(), joint->GetBodyB()); + joint->SetStiffness(stiffness); } float MouseJoint::getFrequency() const { - return joint->GetFrequency(); + float frequency, ratio; + Physics::b2LinearFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB()); + return frequency; } -void MouseJoint::setDampingRatio(float d) +void MouseJoint::setDampingRatio(float ratio) { - joint->SetDampingRatio(d); + float stiffness, damping; + b2LinearStiffness(stiffness, damping, getFrequency(), ratio, joint->GetBodyA(), joint->GetBodyB()); + joint->SetDamping(damping); } float MouseJoint::getDampingRatio() const { - return joint->GetDampingRatio(); + 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 +{ + return joint->GetStiffness(); +} + +void MouseJoint::setDamping(float d) +{ + joint->SetDamping(d); +} + +float MouseJoint::getDamping() const +{ + return joint->GetDamping(); } Body *MouseJoint::getBodyA() const diff --git a/src/modules/physics/box2d/MouseJoint.h b/src/modules/physics/box2d/MouseJoint.h index 648f26eab..f308d7f78 100644 --- a/src/modules/physics/box2d/MouseJoint.h +++ b/src/modules/physics/box2d/MouseJoint.h @@ -76,27 +76,45 @@ public: float getMaxForce() const; /** - * Sets the response speed. + * Sets the response speed. Independent of mass **/ void setFrequency(float hz); /** - * Gets the response speed. + * Gets the response speed. Independent of mass **/ float getFrequency() const; /** - * Sets the damping ratio. - * 0 = no damping, 1 = critical damping. + * Set the spring damping ratio. Independent of mass **/ - void setDampingRatio(float d); + void setDampingRatio(float ratio); /** - * Gets the damping ratio. - * 0 = no damping, 1 = critical damping. + * 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. Dependent of mass + **/ + void setDamping(float ratio); + + /** + * Get the spring damping. Dependent of mass + **/ + float getDamping() const; + virtual Body *getBodyA() const; virtual Body *getBodyB() const; diff --git a/src/modules/physics/box2d/Physics.cpp b/src/modules/physics/box2d/Physics.cpp index 89fadd989..da75cbf65 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->Set(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); } @@ -160,7 +169,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; @@ -196,7 +205,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 &) { @@ -386,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 cec254d29..68518f9e0 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. @@ -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/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/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 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/WeldJoint.cpp b/src/modules/physics/box2d/WeldJoint.cpp index 9259ad46c..30ead28ec 100644 --- a/src/modules/physics/box2d/WeldJoint.cpp +++ b/src/modules/physics/box2d/WeldJoint.cpp @@ -68,22 +68,50 @@ void WeldJoint::init(b2WeldJointDef &def, Body *body1, Body *body2, float xA, fl void WeldJoint::setFrequency(float hz) { - joint->SetFrequency(hz); + float stiffness, damping; + b2LinearStiffness(stiffness, damping, hz, getDampingRatio(), joint->GetBodyA(), joint->GetBodyB()); + joint->SetStiffness(stiffness); } float WeldJoint::getFrequency() const { - return joint->GetFrequency(); + float frequency, ratio; + Physics::b2LinearFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB()); + return frequency; } -void WeldJoint::setDampingRatio(float d) +void WeldJoint::setDampingRatio(float ratio) { - joint->SetDampingRatio(d); + float stiffness, damping; + b2LinearStiffness(stiffness, damping, getFrequency(), ratio, joint->GetBodyA(), joint->GetBodyB()); + joint->SetDamping(damping); } float WeldJoint::getDampingRatio() const { - return joint->GetDampingRatio(); + 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 +{ + return joint->GetStiffness(); +} + +void WeldJoint::setDamping(float d) +{ + joint->SetDamping(d); +} + +float WeldJoint::getDamping() const +{ + return joint->GetDamping(); } float WeldJoint::getReferenceAngle() const diff --git a/src/modules/physics/box2d/WeldJoint.h b/src/modules/physics/box2d/WeldJoint.h index a6e7714c0..e0bd27e68 100644 --- a/src/modules/physics/box2d/WeldJoint.h +++ b/src/modules/physics/box2d/WeldJoint.h @@ -50,27 +50,45 @@ public: virtual ~WeldJoint(); /** - * Sets the response speed. + * Sets the response speed. Independent of mass **/ void setFrequency(float hz); /** - * Gets the response speed. + * Gets the response speed. Independent of mass **/ float getFrequency() const; /** - * Sets the damping ratio. - * 0 = no damping, 1 = critical damping. + * Set the spring damping ratio. Independent of mass **/ - void setDampingRatio(float d); + void setDampingRatio(float ratio); /** - * Gets the damping ratio. - * 0 = no damping, 1 = critical damping. + * 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. Dependent of mass + **/ + void setDamping(float ratio); + + /** + * Get the spring damping. Dependent of mass + **/ + float getDamping() const; + /** * Gets the reference angle. **/ diff --git a/src/modules/physics/box2d/WheelJoint.cpp b/src/modules/physics/box2d/WheelJoint.cpp index 80fa529b9..52b61b998 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) @@ -95,24 +95,52 @@ float WheelJoint::getMotorTorque(float inv_dt) const return Physics::scaleUp(Physics::scaleUp(joint->GetMotorTorque(inv_dt))); } -void WheelJoint::setSpringFrequency(float hz) +void WheelJoint::setFrequency(float hz) { - joint->SetSpringFrequencyHz(hz); + float stiffness, damping; + b2AngularStiffness(stiffness, damping, hz, getDampingRatio(), joint->GetBodyA(), joint->GetBodyB()); + joint->SetStiffness(stiffness); } -float WheelJoint::getSpringFrequency() const +float WheelJoint::getFrequency() const { - return joint->GetSpringFrequencyHz(); + float frequency, ratio; + Physics::b2AngularFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB()); + return frequency; } -void WheelJoint::setSpringDampingRatio(float ratio) +void WheelJoint::setDampingRatio(float ratio) { - joint->SetSpringDampingRatio(ratio); + float stiffness, damping; + b2AngularStiffness(stiffness, damping, getFrequency(), ratio, joint->GetBodyA(), joint->GetBodyB()); + joint->SetDamping(damping); } -float WheelJoint::getSpringDampingRatio() const +float WheelJoint::getDampingRatio() const { - return joint->GetSpringDampingRatio(); + 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 +{ + return joint->GetStiffness(); +} + +void WheelJoint::setDamping(float ratio) +{ + joint->SetDamping(ratio); +} + +float WheelJoint::getDamping() const +{ + return joint->GetDamping(); } int WheelJoint::getAxis(lua_State *L) diff --git a/src/modules/physics/box2d/WheelJoint.h b/src/modules/physics/box2d/WheelJoint.h index 0ee597b3e..453ae9608 100644 --- a/src/modules/physics/box2d/WheelJoint.h +++ b/src/modules/physics/box2d/WheelJoint.h @@ -96,25 +96,44 @@ 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 setSpringFrequency(float hz); + void setFrequency(float hz); /** - * Get the spring frequency, in hertz. + * Gets the response speed. Independent of mass **/ - float getSpringFrequency() const; + float getFrequency() const; /** - * Set the spring damping ratio. + * Set the spring damping ratio. Independent of mass **/ - void setSpringDampingRatio(float ratio); + void setDampingRatio(float ratio); /** - * Get the spring damping ratio. + * Get the spring damping ratio. Independent of mass **/ - float getSpringDampingRatio() const; + 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. Dependent of mass + **/ + void setDamping(float ratio); + + /** + * Get the spring damping. Dependent of mass + **/ + float getDamping() const; /** * Gets the axis unit vector, relative to body1. 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..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 { @@ -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; diff --git a/src/modules/physics/box2d/wrap_Body.cpp b/src/modules/physics/box2d/wrap_Body.cpp index 217306edc..03c0336de 100644 --- a/src/modules/physics/box2d/wrap_Body.cpp +++ b/src/modules/physics/box2d/wrap_Body.cpp @@ -518,7 +518,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; } @@ -548,7 +548,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..d49648d39 100644 --- a/src/modules/physics/box2d/wrap_DistanceJoint.cpp +++ b/src/modules/physics/box2d/wrap_DistanceJoint.cpp @@ -80,6 +80,36 @@ int w_DistanceJoint_getDampingRatio(lua_State *L) 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()); + return 1; +} + static const luaL_Reg w_DistanceJoint_functions[] = { { "setLength", w_DistanceJoint_setLength }, @@ -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_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..e6bce8307 100644 --- a/src/modules/physics/box2d/wrap_MouseJoint.cpp +++ b/src/modules/physics/box2d/wrap_MouseJoint.cpp @@ -96,6 +96,36 @@ int w_MouseJoint_getDampingRatio(lua_State *L) 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()); + return 1; +} + static const luaL_Reg w_MouseJoint_functions[] = { { "setTarget", w_MouseJoint_setTarget }, @@ -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_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; diff --git a/src/modules/physics/box2d/wrap_WeldJoint.cpp b/src/modules/physics/box2d/wrap_WeldJoint.cpp index ada93c2d5..7d1efc020 100644 --- a/src/modules/physics/box2d/wrap_WeldJoint.cpp +++ b/src/modules/physics/box2d/wrap_WeldJoint.cpp @@ -65,6 +65,36 @@ int w_WeldJoint_getDampingRatio(lua_State *L) 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()); + return 1; +} + int w_WeldJoint_getReferenceAngle(lua_State *L) { WeldJoint *t = luax_checkweldjoint(L, 1); @@ -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 11aef43f7..3f2a8e5b6 100644 --- a/src/modules/physics/box2d/wrap_WheelJoint.cpp +++ b/src/modules/physics/box2d/wrap_WheelJoint.cpp @@ -102,33 +102,63 @@ 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->setSpringFrequency(arg1); + t->setFrequency(arg1); return 0; } -int w_WheelJoint_getSpringFrequency(lua_State *L) +int w_WheelJoint_getFrequency(lua_State *L) { WheelJoint *t = luax_checkwheeljoint(L, 1); - lua_pushnumber(L, t->getSpringFrequency()); + lua_pushnumber(L, t->getFrequency()); return 1; } -int w_WheelJoint_setSpringDampingRatio(lua_State *L) +int w_WheelJoint_setDampingRatio(lua_State *L) { WheelJoint *t = luax_checkwheeljoint(L, 1); float arg1 = (float)luaL_checknumber(L, 2); - t->setSpringDampingRatio(arg1); + t->setDampingRatio(arg1); return 0; } -int w_WheelJoint_getSpringDampingRatio(lua_State *L) +int w_WheelJoint_getDampingRatio(lua_State *L) { WheelJoint *t = luax_checkwheeljoint(L, 1); - lua_pushnumber(L, t->getSpringDampingRatio()); + 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); + t->setStiffness(arg1); + return 0; +} + +int w_WheelJoint_getStiffness(lua_State *L) +{ + WheelJoint *t = luax_checkwheeljoint(L, 1); + lua_pushnumber(L, t->getStiffness()); + return 1; +} + +int w_WheelJoint_setDamping(lua_State *L) +{ + WheelJoint *t = luax_checkwheeljoint(L, 1); + float arg1 = (float)luaL_checknumber(L, 2); + t->setDamping(arg1); + return 0; +} + +int w_WheelJoint_getDamping(lua_State *L) +{ + WheelJoint *t = luax_checkwheeljoint(L, 1); + lua_pushnumber(L, t->getDamping()); return 1; } @@ -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 } }; diff --git a/src/modules/system/System.cpp b/src/modules/system/System.cpp index 473518d6b..d5269a11d 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; 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 af63d5000..fce4ad0db 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -94,7 +94,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); @@ -102,12 +102,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); @@ -289,7 +295,7 @@ std::vector Window::getContextAttribsList() const return attribslist; } -bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowflags, graphics::Graphics::Renderer renderer, int msaa, bool stencil, int depth) +bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowflags, graphics::Graphics::Renderer renderer) { bool needsglcontext = (windowflags & SDL_WINDOW_OPENGL) != 0; #ifdef LOVE_GRAPHICS_METAL @@ -369,10 +375,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(); @@ -380,33 +385,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 && glcontext) { // Store the successful context attributes so we can re-use them in @@ -481,6 +467,9 @@ bool Window::setWindow(int width, int height, WindowSettings *settings) auto renderer = graphics != nullptr ? graphics->getRenderer() : graphics::Graphics::RENDERER_NONE; + if (isOpen()) + updateSettings(this->settings, false); + WindowSettings f; if (settings) @@ -500,54 +489,11 @@ bool Window::setWindow(int width, int height, WindowSettings *settings) height = mode.h; } - Uint32 sdlflags = 0; - - if (renderer == graphics::Graphics::RENDERER_OPENGL) - sdlflags |= SDL_WINDOW_OPENGL; - -#ifdef LOVE_GRAPHICS_METAL - if (renderer == graphics::Graphics::RENDERER_METAL) - sdlflags |= SDL_WINDOW_METAL; -#endif - // 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 (f.highdpi) - sdlflags |= SDL_WINDOW_ALLOW_HIGHDPI; - int x = f.x; int y = f.y; @@ -567,10 +513,81 @@ 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, renderer, f.msaa, f.stencil, f.depth)) - 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 (renderer == graphics::Graphics::RENDERER_OPENGL) + sdlflags |= SDL_WINDOW_OPENGL; + +#ifdef LOVE_GRAPHICS_METAL + if (renderer == graphics::Graphics::RENDERER_METAL) + sdlflags |= SDL_WINDOW_METAL; +#endif + + if (isOpen()) + { + if (SDL_SetWindowFullscreen(window, sdlflags) == 0 && renderer == graphics::Graphics::RENDERER_OPENGL) + SDL_GL_MakeCurrent(window, glcontext); + + 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); + } + 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, renderer)) + return false; + + needsetmode = true; + } // Make sure the window keeps any previously set icon. setIcon(icon.get()); @@ -581,7 +598,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); @@ -595,15 +612,23 @@ bool Window::setWindow(int width, int height, WindowSettings *settings) double scaledw, scaledh; fromPixels((double) pixelWidth, (double) pixelHeight, scaledw, scaledh); - void *context = nullptr; - if (renderer == graphics::Graphics::RENDERER_OPENGL) - context = (void *) glcontext; + if (needsetmode) + { + void *context = nullptr; + if (renderer == graphics::Graphics::RENDERER_OPENGL) + context = (void *) glcontext; #ifdef LOVE_GRAPHICS_METAL - if (renderer == graphics::Graphics::RENDERER_METAL && metalView) - context = (void *) SDL_Metal_GetLayer(metalView); + if (renderer == graphics::Graphics::RENDERER_METAL && metalView) + context = (void *) SDL_Metal_GetLayer(metalView); #endif - graphics->setMode(context, (int) scaledw, (int) scaledh, pixelWidth, pixelHeight, f.stencil, f.depth); + graphics->setMode(context, (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 @@ -680,7 +705,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 @@ -689,17 +715,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; - - if ((wflags & SDL_WINDOW_OPENGL) != 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; @@ -773,7 +788,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; @@ -812,9 +827,10 @@ bool Window::setFullscreen(bool fullscreen, Window::FullscreenType fstype) { if (glcontext) SDL_GL_MakeCurrent(window, glcontext); + updateSettings(newsettings, true); - // Apparently this gets un-set when we exit fullscreen (at least in macOS). + // 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 b177b231e..d2e87a1dc 100644 --- a/src/modules/window/sdl/Window.h +++ b/src/modules/window/sdl/Window.h @@ -131,8 +131,6 @@ public: private: - void close(bool allowExceptions); - struct ContextAttribs { int versionMajor; @@ -141,11 +139,13 @@ private: bool debug; }; - void setGLFramebufferAttributes(int msaa, bool sRGB, bool stencil, int depth); + void close(bool allowExceptions); + + 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, graphics::Graphics::Renderer renderer, int msaa, bool stencil, int depth); + bool createWindowAndContext(int x, int y, int w, int h, Uint32 windowflags, graphics::Graphics::Renderer renderer); // Update the saved window settings based on the window's actual state. void updateSettings(const WindowSettings &newsettings, bool updateGraphicsViewport); 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 086799d63..71604419d 100644 --- a/src/scripts/nogame.lua +++ b/src/scripts/nogame.lua @@ -3277,7 +3277,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 8fb0bf7a9..213f4f90a 100644 --- a/src/scripts/nogame.lua.h +++ b/src/scripts/nogame.lua.h @@ -12123,8 +12123,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,