Showing preview only (2,248K chars total). Download the full file or copy to clipboard to get everything.
Repository: ThePhysicsGuys/Physics3D
Branch: master
Commit: 00691dffa552
Files: 548
Total size: 2.1 MB
Directory structure:
gitextract_pl6iqfhu/
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ └── workflows/
│ ├── msvcBuild.yml
│ └── ubuntuBuild.yml
├── .gitignore
├── CMakeLists.txt
├── LICENSE.md
├── Physics3D/
│ ├── CMakeLists.txt
│ ├── Physics3D.vcxproj
│ ├── boundstree/
│ │ ├── boundsTree.cpp
│ │ ├── boundsTree.h
│ │ ├── boundsTreeAVX.cpp
│ │ ├── boundsTreeSSE.cpp
│ │ └── filters/
│ │ ├── outOfBoundsFilter.h
│ │ ├── rayIntersectsBoundsFilter.h
│ │ ├── visibilityFilter.cpp
│ │ └── visibilityFilter.h
│ ├── colissionBuffer.h
│ ├── constraints/
│ │ ├── ballConstraint.cpp
│ │ ├── ballConstraint.h
│ │ ├── barConstraint.cpp
│ │ ├── barConstraint.h
│ │ ├── constraint.cpp
│ │ ├── constraint.h
│ │ ├── constraintGroup.cpp
│ │ ├── constraintGroup.h
│ │ ├── constraintImpl.h
│ │ ├── hingeConstraint.cpp
│ │ └── hingeConstraint.h
│ ├── datastructures/
│ │ ├── alignedPtr.h
│ │ ├── aligned_alloc.cpp
│ │ ├── aligned_alloc.h
│ │ ├── buffers.h
│ │ ├── compactPtrDataPair.h
│ │ ├── iteratorEnd.h
│ │ ├── iteratorFactory.h
│ │ ├── monotonicTree.h
│ │ ├── parallelArray.h
│ │ ├── sharedArray.h
│ │ ├── smartPointers.h
│ │ ├── uniqueArrayPtr.h
│ │ ├── unmanagedArray.h
│ │ └── unorderedVector.h
│ ├── externalforces/
│ │ ├── directionalGravity.cpp
│ │ ├── directionalGravity.h
│ │ ├── externalForce.cpp
│ │ ├── externalForce.h
│ │ ├── magnetForce.cpp
│ │ └── magnetForce.h
│ ├── geometry/
│ │ ├── builtinShapeClasses.cpp
│ │ ├── builtinShapeClasses.h
│ │ ├── computationBuffer.cpp
│ │ ├── computationBuffer.h
│ │ ├── convexShapeBuilder.cpp
│ │ ├── convexShapeBuilder.h
│ │ ├── genericCollidable.h
│ │ ├── genericIntersection.cpp
│ │ ├── genericIntersection.h
│ │ ├── indexedShape.cpp
│ │ ├── indexedShape.h
│ │ ├── intersection.cpp
│ │ ├── intersection.h
│ │ ├── polyhedron.cpp
│ │ ├── polyhedron.h
│ │ ├── scalableInertialMatrix.h
│ │ ├── shape.cpp
│ │ ├── shape.h
│ │ ├── shapeBuilder.cpp
│ │ ├── shapeBuilder.h
│ │ ├── shapeClass.cpp
│ │ ├── shapeClass.h
│ │ ├── shapeCreation.cpp
│ │ ├── shapeCreation.h
│ │ ├── shapeLibrary.cpp
│ │ ├── shapeLibrary.h
│ │ ├── triangleMesh.cpp
│ │ ├── triangleMesh.h
│ │ ├── triangleMeshAVX.cpp
│ │ ├── triangleMeshCommon.h
│ │ ├── triangleMeshSSE.cpp
│ │ └── triangleMeshSSE4.cpp
│ ├── hardconstraints/
│ │ ├── constraintTemplates.h
│ │ ├── controller/
│ │ │ ├── constController.h
│ │ │ ├── sineWaveController.cpp
│ │ │ └── sineWaveController.h
│ │ ├── fixedConstraint.cpp
│ │ ├── fixedConstraint.h
│ │ ├── hardConstraint.cpp
│ │ ├── hardConstraint.h
│ │ ├── hardPhysicalConnection.cpp
│ │ ├── hardPhysicalConnection.h
│ │ ├── motorConstraint.cpp
│ │ ├── motorConstraint.h
│ │ └── sinusoidalPistonConstraint.h
│ ├── inertia.cpp
│ ├── inertia.h
│ ├── layer.cpp
│ ├── layer.h
│ ├── math/
│ │ ├── boundingBox.h
│ │ ├── bounds.h
│ │ ├── cframe.h
│ │ ├── constants.h
│ │ ├── fix.h
│ │ ├── globalCFrame.h
│ │ ├── globalTransform.h
│ │ ├── linalg/
│ │ │ ├── commonMatrices.h
│ │ │ ├── eigen.cpp
│ │ │ ├── eigen.h
│ │ │ ├── largeMatrix.h
│ │ │ ├── largeMatrixAlgorithms.h
│ │ │ ├── mat.h
│ │ │ ├── quat.h
│ │ │ ├── trigonometry.cpp
│ │ │ ├── trigonometry.h
│ │ │ └── vec.h
│ │ ├── mathUtil.h
│ │ ├── position.h
│ │ ├── predefinedTaylorExpansions.h
│ │ ├── ray.h
│ │ ├── rotation.h
│ │ ├── taylorExpansion.h
│ │ ├── transform.h
│ │ └── utils.h
│ ├── misc/
│ │ ├── catchable_assert.h
│ │ ├── cpuid.cpp
│ │ ├── cpuid.h
│ │ ├── debug.cpp
│ │ ├── debug.h
│ │ ├── physicsProfiler.cpp
│ │ ├── physicsProfiler.h
│ │ ├── profiling.h
│ │ ├── serialization/
│ │ │ ├── dynamicSerialize.h
│ │ │ ├── serialization.cpp
│ │ │ ├── serialization.h
│ │ │ ├── serializeBasicTypes.cpp
│ │ │ ├── serializeBasicTypes.h
│ │ │ └── sharedObjectSerializer.h
│ │ ├── toString.h
│ │ ├── unreachable.h
│ │ ├── validityHelper.cpp
│ │ └── validityHelper.h
│ ├── motion.h
│ ├── part.cpp
│ ├── part.h
│ ├── physical.cpp
│ ├── physical.h
│ ├── relativeMotion.h
│ ├── rigidBody.cpp
│ ├── rigidBody.h
│ ├── softlinks/
│ │ ├── alignmentLink.cpp
│ │ ├── alignmentLink.h
│ │ ├── elasticLink.cpp
│ │ ├── elasticLink.h
│ │ ├── magneticLink.cpp
│ │ ├── magneticLink.h
│ │ ├── softLink.cpp
│ │ ├── softLink.h
│ │ ├── springLink.cpp
│ │ └── springLink.h
│ ├── threading/
│ │ ├── physicsThread.cpp
│ │ ├── physicsThread.h
│ │ ├── sharedLockGuard.h
│ │ ├── threadPool.h
│ │ ├── upgradeableMutex.cpp
│ │ └── upgradeableMutex.h
│ ├── world.cpp
│ ├── world.h
│ ├── worldIteration.h
│ ├── worldPhysics.cpp
│ └── worldPhysics.h
├── Physics3D.sln
├── README.md
├── _config.yml
├── application/
│ ├── application.cpp
│ ├── application.h
│ ├── application.rc
│ ├── application.vcxproj
│ ├── builtinWorlds.cpp
│ ├── builtinWorlds.h
│ ├── core.cpp
│ ├── core.h
│ ├── debugData.natvis
│ ├── ecs/
│ │ ├── components.h
│ │ └── entityBuilder.h
│ ├── eventHandler.cpp
│ ├── eventHandler.h
│ ├── extendedPart.cpp
│ ├── extendedPart.h
│ ├── input/
│ │ ├── playerController.cpp
│ │ ├── playerController.h
│ │ ├── standardInputHandler.cpp
│ │ └── standardInputHandler.h
│ ├── io/
│ │ ├── saveDialog.cpp
│ │ ├── saveDialog.h
│ │ ├── serialization.cpp
│ │ └── serialization.h
│ ├── layer/
│ │ ├── cameraLayer.cpp
│ │ ├── cameraLayer.h
│ │ ├── constraintLayer.cpp
│ │ ├── constraintLayer.h
│ │ ├── debugLayer.cpp
│ │ ├── debugLayer.h
│ │ ├── debugOverlay.cpp
│ │ ├── debugOverlay.h
│ │ ├── guiLayer.cpp
│ │ ├── guiLayer.h
│ │ ├── imguiLayer.cpp
│ │ ├── imguiLayer.h
│ │ ├── modelLayer.cpp
│ │ ├── modelLayer.h
│ │ ├── pickerLayer.cpp
│ │ ├── pickerLayer.h
│ │ ├── postprocessLayer.cpp
│ │ ├── postprocessLayer.h
│ │ ├── shadowLayer.cpp
│ │ ├── shadowLayer.h
│ │ ├── skyboxLayer.cpp
│ │ ├── skyboxLayer.h
│ │ ├── testLayer.cpp
│ │ └── testLayer.h
│ ├── legacy/
│ │ └── frames.h
│ ├── math.natvis
│ ├── picker/
│ │ ├── ray.cpp
│ │ ├── ray.h
│ │ ├── selection.cpp
│ │ ├── selection.h
│ │ └── tools/
│ │ ├── alignmentLinkTool.cpp
│ │ ├── alignmentLinkTool.h
│ │ ├── attachmentTool.cpp
│ │ ├── attachmentTool.h
│ │ ├── elasticLinkTool.cpp
│ │ ├── elasticLinkTool.h
│ │ ├── fixedConstraintTool.cpp
│ │ ├── fixedConstraintTool.h
│ │ ├── magneticLinkTool.cpp
│ │ ├── magneticLinkTool.h
│ │ ├── motorConstraintTool.cpp
│ │ ├── motorConstraintTool.h
│ │ ├── pathTool.cpp
│ │ ├── pathTool.h
│ │ ├── pistonConstraintTool.cpp
│ │ ├── pistonConstraintTool.h
│ │ ├── regionSelectionTool.cpp
│ │ ├── regionSelectionTool.h
│ │ ├── rotationTool.cpp
│ │ ├── rotationTool.h
│ │ ├── scaleTool.cpp
│ │ ├── scaleTool.h
│ │ ├── selectionTool.cpp
│ │ ├── selectionTool.h
│ │ ├── springLinkTool.cpp
│ │ ├── springLinkTool.h
│ │ ├── toolSpacing.h
│ │ ├── translationTool.cpp
│ │ └── translationTool.h
│ ├── resource.h
│ ├── resources.cpp
│ ├── resources.h
│ ├── shader/
│ │ ├── basicShader.cpp
│ │ ├── basicShader.h
│ │ ├── shaderBase.cpp
│ │ ├── shaderBase.h
│ │ ├── shaders.cpp
│ │ └── shaders.h
│ ├── view/
│ │ ├── camera.cpp
│ │ ├── camera.h
│ │ ├── debugFrame.cpp
│ │ ├── debugFrame.h
│ │ ├── ecsFrame.cpp
│ │ ├── ecsFrame.h
│ │ ├── environmentFrame.cpp
│ │ ├── environmentFrame.h
│ │ ├── frames.cpp
│ │ ├── frames.h
│ │ ├── layerFrame.cpp
│ │ ├── layerFrame.h
│ │ ├── propertiesFrame.cpp
│ │ ├── propertiesFrame.h
│ │ ├── resourceFrame.cpp
│ │ ├── resourceFrame.h
│ │ ├── screen.cpp
│ │ ├── screen.h
│ │ ├── toolbarFrame.cpp
│ │ └── toolbarFrame.h
│ ├── view.natvis
│ ├── worldBuilder.cpp
│ ├── worldBuilder.h
│ ├── worlds.cpp
│ └── worlds.h
├── benchmarks/
│ ├── basicWorld.cpp
│ ├── benchmark.cpp
│ ├── benchmark.h
│ ├── benchmarks.vcxproj
│ ├── complexObjectBenchmark.cpp
│ ├── ecsBenchmark.cpp
│ ├── getBoundsPerformance.cpp
│ ├── manyCubesBenchmark.cpp
│ ├── rotationBenchmark.cpp
│ ├── threadResponseTime.cpp
│ ├── worldBenchmark.cpp
│ └── worldBenchmark.h
├── engine/
│ ├── core.cpp
│ ├── core.h
│ ├── ecs/
│ │ └── registry.h
│ ├── engine.vcxproj
│ ├── event/
│ │ ├── event.h
│ │ ├── keyEvent.h
│ │ ├── mouseEvent.h
│ │ └── windowEvent.h
│ ├── input/
│ │ ├── inputHandler.cpp
│ │ ├── inputHandler.h
│ │ ├── keyboard.cpp
│ │ ├── keyboard.h
│ │ ├── modifiers.cpp
│ │ ├── modifiers.h
│ │ ├── mouse.cpp
│ │ └── mouse.h
│ ├── io/
│ │ ├── export.cpp
│ │ ├── export.h
│ │ ├── import.cpp
│ │ └── import.h
│ ├── layer/
│ │ ├── layer.h
│ │ ├── layerStack.cpp
│ │ └── layerStack.h
│ ├── options/
│ │ ├── keyboardOptions.cpp
│ │ └── keyboardOptions.h
│ ├── resource/
│ │ ├── meshResource.cpp
│ │ └── meshResource.h
│ └── tool/
│ ├── buttonTool.h
│ ├── stateTool.h
│ ├── tool.h
│ ├── toolManager.cpp
│ └── toolManager.h
├── examples/
│ ├── CMakeLists.txt
│ ├── examples.vcxproj
│ └── openglBasic.cpp
├── graphics/
│ ├── batch/
│ │ ├── batch.h
│ │ ├── batchConfig.h
│ │ ├── commandBatch.h
│ │ ├── guiBatch.h
│ │ ├── instanceBatch.h
│ │ └── instanceBatchManager.h
│ ├── bindable.cpp
│ ├── bindable.h
│ ├── buffers/
│ │ ├── bufferLayout.cpp
│ │ ├── bufferLayout.h
│ │ ├── frameBuffer.cpp
│ │ ├── frameBuffer.h
│ │ ├── indexBuffer.cpp
│ │ ├── indexBuffer.h
│ │ ├── renderBuffer.cpp
│ │ ├── renderBuffer.h
│ │ ├── vertexArray.cpp
│ │ ├── vertexArray.h
│ │ ├── vertexBuffer.cpp
│ │ └── vertexBuffer.h
│ ├── component.natvis
│ ├── core.cpp
│ ├── core.h
│ ├── debug/
│ │ ├── guiDebug.cpp
│ │ ├── guiDebug.h
│ │ ├── profilerUI.cpp
│ │ ├── profilerUI.h
│ │ ├── threePhaseBuffer.h
│ │ ├── visualDebug.cpp
│ │ └── visualDebug.h
│ ├── ecs/
│ │ ├── components.h
│ │ └── materials.h
│ ├── extendedTriangleMesh.cpp
│ ├── extendedTriangleMesh.h
│ ├── font.cpp
│ ├── font.h
│ ├── glfwUtils.cpp
│ ├── glfwUtils.h
│ ├── graphics.vcxproj
│ ├── gui/
│ │ ├── color.h
│ │ ├── gui.cpp
│ │ ├── gui.h
│ │ ├── guiUtils.cpp
│ │ ├── guiUtils.h
│ │ ├── imgui/
│ │ │ ├── imguiExtension.h
│ │ │ ├── imguiStyle.cpp
│ │ │ ├── imguiStyle.h
│ │ │ ├── legacy_imgui_impl_glfw.cpp
│ │ │ ├── legacy_imgui_impl_glfw.h
│ │ │ ├── legacy_imgui_impl_opengl3.cpp
│ │ │ └── legacy_imgui_impl_opengl3.h
│ │ └── orderedVector.h
│ ├── legacy/
│ │ ├── button.cpp
│ │ ├── button.h
│ │ ├── checkBox.cpp
│ │ ├── checkBox.h
│ │ ├── colorPicker.cpp
│ │ ├── colorPicker.h
│ │ ├── component.h
│ │ ├── container.cpp
│ │ ├── container.h
│ │ ├── cshader.cpp
│ │ ├── cshader.h
│ │ ├── directionEditor.cpp
│ │ ├── directionEditor.h
│ │ ├── frame.cpp
│ │ ├── frame.h
│ │ ├── gshader.cpp
│ │ ├── gshader.h
│ │ ├── image.cpp
│ │ ├── image.h
│ │ ├── label.cpp
│ │ ├── label.h
│ │ ├── layout.cpp
│ │ ├── layout.h
│ │ ├── panel.cpp
│ │ ├── panel.h
│ │ ├── shader.cpp
│ │ ├── shader.h
│ │ ├── shaderLexer.cpp
│ │ ├── shaderLexer.h
│ │ ├── shaderParser.cpp
│ │ ├── shaderParser.h
│ │ ├── slider.cpp
│ │ ├── slider.h
│ │ ├── text.cpp
│ │ └── text.h
│ ├── mesh/
│ │ ├── abstractMesh.cpp
│ │ ├── abstractMesh.h
│ │ ├── arrayMesh.cpp
│ │ ├── arrayMesh.h
│ │ ├── indexedMesh.cpp
│ │ ├── indexedMesh.h
│ │ ├── pointMesh.cpp
│ │ ├── pointMesh.h
│ │ ├── primitive.h
│ │ ├── vectorMesh.cpp
│ │ └── vectorMesh.h
│ ├── meshRegistry.cpp
│ ├── meshRegistry.h
│ ├── path/
│ │ ├── path.cpp
│ │ ├── path.h
│ │ ├── path3D.cpp
│ │ └── path3D.h
│ ├── renderer.cpp
│ ├── renderer.h
│ ├── resource/
│ │ ├── fontResource.cpp
│ │ ├── fontResource.h
│ │ ├── shaderResource.cpp
│ │ ├── shaderResource.h
│ │ ├── textureResource.cpp
│ │ └── textureResource.h
│ ├── shader/
│ │ ├── lexer.cpp
│ │ ├── lexer.h
│ │ ├── parser.cpp
│ │ ├── parser.h
│ │ ├── propertiesParser.cpp
│ │ ├── propertiesParser.h
│ │ ├── shader.cpp
│ │ ├── shader.h
│ │ ├── shaders.cpp
│ │ └── shaders.h
│ ├── texture.cpp
│ └── texture.h
├── install/
│ ├── clean.bat
│ ├── clean.sh
│ ├── setup.bat
│ ├── setup.sh
│ ├── setupBuild.bat
│ ├── setupBuild.sh
│ ├── setupBuildUbuntu.sh
│ ├── setupDependencies.bat
│ ├── setupDependencies.sh
│ ├── setupDependenciesUbuntu.sh
│ └── setupUbuntu.sh
├── res/
│ ├── default_imgui.ini
│ └── shaders/
│ ├── basic.shader
│ ├── blur.shader
│ ├── compute.shader
│ ├── debug.shader
│ ├── depth.shader
│ ├── depthbuffer.shader
│ ├── font.shader
│ ├── gui.shader
│ ├── instance.shader
│ ├── lighting.shader
│ ├── line.shader
│ ├── mask.shader
│ ├── origin.shader
│ ├── point.shader
│ ├── postprocess.shader
│ ├── quad.shader
│ ├── sky.shader
│ ├── skybox.shader
│ ├── test.shader
│ └── vector.shader
├── tests/
│ ├── boundsTree2Tests.cpp
│ ├── compare.h
│ ├── constraintTests.cpp
│ ├── ecsTests.cpp
│ ├── estimateMotion.cpp
│ ├── estimateMotion.h
│ ├── estimationTests.cpp
│ ├── generators.cpp
│ ├── generators.h
│ ├── geometryTests.cpp
│ ├── guiTests.cpp
│ ├── indexedShapeTests.cpp
│ ├── inertiaTests.cpp
│ ├── jointTests.cpp
│ ├── lexerTests.cpp
│ ├── mathTests.cpp
│ ├── motionTests.cpp
│ ├── physicalStructureTests.cpp
│ ├── physicsTests.cpp
│ ├── randomValues.h
│ ├── rotationTests.cpp
│ ├── simulation.h
│ ├── testFrameworkConsistencyTests.cpp
│ ├── testValues.cpp
│ ├── testValues.h
│ ├── tests.vcxproj
│ ├── testsMain.cpp
│ └── testsMain.h
├── util/
│ ├── cmdParser.h
│ ├── fileUtils.cpp
│ ├── fileUtils.h
│ ├── iteratorUtils.h
│ ├── log.cpp
│ ├── log.h
│ ├── parseCPUIDArgs.h
│ ├── properties.cpp
│ ├── properties.h
│ ├── resource/
│ │ ├── resource.cpp
│ │ ├── resource.h
│ │ ├── resourceDescriptor.h
│ │ ├── resourceLoader.cpp
│ │ ├── resourceLoader.h
│ │ ├── resourceManager.cpp
│ │ └── resourceManager.h
│ ├── stringUtil.cpp
│ ├── stringUtil.h
│ ├── systemVariables.cpp
│ ├── systemVariables.h
│ ├── terminalColor.cpp
│ ├── terminalColor.h
│ ├── tracker.h
│ ├── typetraits.h
│ ├── util.vcxproj
│ ├── valueCycle.cpp
│ └── valueCycle.h
└── world.grammar
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
================================================
FILE: .github/workflows/msvcBuild.yml
================================================
name: MSVC
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
buildMSVC:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- name: setup
run: install\setup.bat
- name: make
run: cmake --build build --parallel
================================================
FILE: .github/workflows/ubuntuBuild.yml
================================================
name: Ubuntu
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
buildUbuntu:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: setup
run: sh install/setupUbuntu.sh
- name: make
run: cmake --build build --parallel
================================================
FILE: .gitignore
================================================
# Files possibly generated by Physics3D
res/.properties
imgui.ini
res/imgui.ini
*.parts
*.nativeParts
*.world
*.obj
*.bobj
# Visual Studio
**.vcxproj.filters
**.vcxproj.user
**.aps
*.db
*.opendb
*.TMP
.vs/
Debug/
Release/
x64/
x86/
lib/
ipch/
# Visual studio code
.vscode/
# CLion
.idea/
cmake-build-debug/
# Other build systems
include/
vcpkg/
build/
build2/
build_debug/
*.log
SHADERed/
res/xcf/
*.ruleset
Hexinator.lnk
Physics3D.sln.DotSettings.user
================================================
FILE: CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.10)
project(Physics3D-application VERSION 1.0)
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
message(STATUS "Building with: ${CMAKE_CXX_COMPILER_ID}")
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:AVX2")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /O2 /Oi /ot /GL")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -mtune=native")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -fsanitize=address")
set(OpenGL_GL_PREFERENCE "GLVND")
#running benchmarks showed this to be a pessimization
#set(CMAKE_INTERPROCEDURAL_OPTIMIZATION True)
#surprisingly, also a pessimization
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffast-math")
endif()
find_package(glfw3 3.2 REQUIRED)
find_package(OpenGL REQUIRED)
find_package(GLEW REQUIRED)
find_package(Freetype REQUIRED)
find_package(Threads REQUIRED)
include_directories(PRIVATE "${GLFW_DIR}/include")
include_directories(PRIVATE "${GLEW_DIR}/include")
include_directories(PRIVATE "${FREETYPE_INCLUDE_DIRS}")
include_directories(PRIVATE "include")
add_library(util STATIC
util/terminalColor.cpp
util/log.cpp
util/properties.cpp
util/stringUtil.cpp
util/fileUtils.cpp
util/valueCycle.cpp
util/systemVariables.cpp
util/resource/resource.cpp
util/resource/resourceLoader.cpp
util/resource/resourceManager.cpp
)
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU)
target_link_libraries(util stdc++fs)
endif()
# Adds the Physics3D library
add_subdirectory(Physics3D)
add_executable(benchmarks
benchmarks/benchmark.cpp
benchmarks/basicWorld.cpp
benchmarks/complexObjectBenchmark.cpp
benchmarks/getBoundsPerformance.cpp
benchmarks/manyCubesBenchmark.cpp
benchmarks/worldBenchmark.cpp
benchmarks/rotationBenchmark.cpp
benchmarks/ecsBenchmark.cpp
benchmarks/threadResponseTime.cpp
)
add_library(imguiInclude STATIC
include/imgui/imgui.cpp
include/imgui/imgui_demo.cpp
include/imgui/imgui_draw.cpp
include/imgui/imgui_impl_glfw.cpp
include/imgui/imgui_impl_opengl3.cpp
include/imgui/imgui_widgets.cpp
)
add_library(graphics STATIC
graphics/glfwUtils.cpp
graphics/bindable.cpp
graphics/core.cpp
graphics/font.cpp
graphics/renderer.cpp
graphics/texture.cpp
graphics/extendedTriangleMesh.cpp
graphics/meshRegistry.cpp
graphics/buffers/bufferLayout.cpp
graphics/buffers/frameBuffer.cpp
graphics/buffers/indexBuffer.cpp
graphics/buffers/renderBuffer.cpp
graphics/buffers/vertexArray.cpp
graphics/buffers/vertexBuffer.cpp
graphics/debug/guiDebug.cpp
graphics/debug/profilerUI.cpp
graphics/debug/visualDebug.cpp
graphics/gui/gui.cpp
graphics/gui/guiUtils.cpp
graphics/gui/imgui/imguiStyle.cpp
graphics/mesh/abstractMesh.cpp
graphics/mesh/arrayMesh.cpp
graphics/mesh/indexedMesh.cpp
graphics/mesh/pointMesh.cpp
graphics/mesh/vectorMesh.cpp
graphics/path/path.cpp
graphics/path/path3D.cpp
graphics/resource/fontResource.cpp
graphics/resource/shaderResource.cpp
graphics/resource/textureResource.cpp
graphics/shader/shader.cpp
graphics/shader/lexer.cpp
graphics/shader/parser.cpp
graphics/shader/shaders.cpp
graphics/shader/propertiesParser.cpp
)
add_library(engine STATIC
engine/core.cpp
engine/input/inputHandler.cpp
engine/input/keyboard.cpp
engine/input/modifiers.cpp
engine/input/mouse.cpp
engine/io/export.cpp
engine/io/import.cpp
engine/layer/layerStack.cpp
engine/tool/toolManager.cpp
engine/options/keyboardOptions.cpp
engine/resource/meshResource.cpp
)
add_executable(tests
tests/testsMain.cpp
tests/estimateMotion.cpp
tests/testValues.cpp
tests/generators.cpp
tests/mathTests.cpp
tests/rotationTests.cpp
tests/motionTests.cpp
tests/geometryTests.cpp
tests/estimationTests.cpp
tests/constraintTests.cpp
tests/jointTests.cpp
tests/boundsTree2Tests.cpp
tests/guiTests.cpp
tests/indexedShapeTests.cpp
tests/physicalStructureTests.cpp
tests/physicsTests.cpp
tests/inertiaTests.cpp
tests/testFrameworkConsistencyTests.cpp
tests/ecsTests.cpp
tests/lexerTests.cpp
)
add_executable(application
application/core.cpp
application/application.cpp
application/eventHandler.cpp
application/extendedPart.cpp
application/resources.cpp
application/worldBuilder.cpp
application/builtinWorlds.cpp
application/worlds.cpp
application/input/standardInputHandler.cpp
application/input/playerController.cpp
application/io/saveDialog.cpp
application/io/serialization.cpp
application/layer/constraintLayer.cpp
application/layer/debugLayer.cpp
application/layer/debugOverlay.cpp
application/layer/guiLayer.cpp
application/layer/modelLayer.cpp
application/layer/pickerLayer.cpp
application/layer/postprocessLayer.cpp
application/layer/skyboxLayer.cpp
application/layer/testLayer.cpp
application/layer/cameraLayer.cpp
application/layer/shadowLayer.cpp
application/layer/imguiLayer.cpp
application/picker/ray.cpp
application/picker/selection.cpp
application/picker/tools/selectionTool.cpp
application/picker/tools/translationTool.cpp
application/picker/tools/rotationTool.cpp
application/picker/tools/scaleTool.cpp
application/picker/tools/regionSelectionTool.cpp
application/picker/tools/attachmentTool.cpp
application/picker/tools/fixedConstraintTool.cpp
application/picker/tools/motorConstraintTool.cpp
application/picker/tools/pistonConstraintTool.cpp
application/picker/tools/elasticLinkTool.cpp
application/picker/tools/magneticLinkTool.cpp
application/picker/tools/springLinkTool.cpp
application/picker/tools/alignmentLinkTool.cpp
application/picker/tools/pathTool.cpp
application/shader/shaders.cpp
application/shader/basicShader.cpp
application/shader/shaderBase.cpp
application/view/camera.cpp
application/view/frames.cpp
application/view/screen.cpp
application/view/debugFrame.cpp
application/view/layerFrame.cpp
application/view/ecsFrame.cpp
application/view/propertiesFrame.cpp
application/view/resourceFrame.cpp
application/view/environmentFrame.cpp
application/view/toolbarFrame.cpp
)
target_include_directories(tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(benchmarks PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(graphics PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(engine PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(application PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(graphics PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/graphics")
target_include_directories(engine PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/engine")
target_include_directories(application PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/application")
target_link_libraries(tests util)
target_link_libraries(tests Physics3D)
target_link_libraries(tests graphics)
target_link_libraries(tests engine)
target_link_libraries(tests Threads::Threads)
target_link_libraries(benchmarks util)
target_link_libraries(benchmarks Physics3D)
target_link_libraries(benchmarks Threads::Threads)
target_link_libraries(graphics imguiInclude)
target_link_libraries(graphics Physics3D)
target_link_libraries(engine graphics)
target_link_libraries(application util)
target_link_libraries(application Physics3D)
target_link_libraries(application graphics)
target_link_libraries(application engine)
#target_link_libraries(application ${GLFW_LIBRARIES})
target_link_libraries(application glfw)
#target_link_libraries(application ${OPENGL_LIBRARIES})
target_link_libraries(application OpenGL::GL)
#target_link_libraries(application ${GLEW_LIBRARIES})
target_link_libraries(application GLEW::GLEW)
target_link_libraries(application ${FREETYPE_LIBRARIES})
target_link_libraries(application Threads::Threads)
# install(TARGETS benchmarks DESTINATION bin)
================================================
FILE: LICENSE.md
================================================
MIT License
Copyright (c) 2018 ThePhysicsGuys
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.
================================================
FILE: Physics3D/CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.10)
project(Physics3D VERSION 0.9)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED True)
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:AVX2")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /O2 /Oi /ot /GL")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -mtune=native -fno-math-errno")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast")
#running benchmarks showed this to be a pessimization
#set(CMAKE_INTERPROCEDURAL_OPTIMIZATION True)
#surprisingly, also a pessimization
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffast-math")
endif()
add_library(Physics3D STATIC
part.cpp
physical.cpp
rigidBody.cpp
layer.cpp
world.cpp
worldPhysics.cpp
inertia.cpp
math/linalg/eigen.cpp
math/linalg/trigonometry.cpp
geometry/computationBuffer.cpp
geometry/convexShapeBuilder.cpp
geometry/genericIntersection.cpp
geometry/indexedShape.cpp
geometry/intersection.cpp
geometry/triangleMesh.cpp
geometry/triangleMeshSSE.cpp
geometry/triangleMeshSSE4.cpp
geometry/triangleMeshAVX.cpp
geometry/polyhedron.cpp
geometry/shape.cpp
geometry/shapeBuilder.cpp
geometry/shapeClass.cpp
geometry/shapeCreation.cpp
geometry/builtinShapeClasses.cpp
geometry/shapeLibrary.cpp
datastructures/aligned_alloc.cpp
boundstree/boundsTree.cpp
boundstree/boundsTreeAVX.cpp
boundstree/filters/visibilityFilter.cpp
hardconstraints/fixedConstraint.cpp
hardconstraints/hardConstraint.cpp
hardconstraints/hardPhysicalConnection.cpp
hardconstraints/motorConstraint.cpp
hardconstraints/controller/sineWaveController.cpp
constraints/constraint.cpp
constraints/constraintGroup.cpp
constraints/ballConstraint.cpp
constraints/hingeConstraint.cpp
constraints/barConstraint.cpp
softlinks/softLink.cpp
softlinks/springLink.cpp
softlinks/elasticLink.cpp
softlinks/magneticLink.cpp
softlinks/alignmentLink.cpp
externalforces/directionalGravity.cpp
externalforces/externalForce.cpp
externalforces/magnetForce.cpp
threading/upgradeableMutex.cpp
threading/physicsThread.cpp
misc/debug.cpp
misc/cpuid.cpp
misc/validityHelper.cpp
misc/physicsProfiler.cpp
misc/serialization/serialization.cpp
misc/serialization/serializeBasicTypes.cpp
)
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set_source_files_properties(geometry/triangleMeshSSE.cpp PROPERTIES COMPILE_FLAGS /arch:SSE2)
set_source_files_properties(geometry/triangleMeshSSE4.cpp PROPERTIES COMPILE_FLAGS /arch:SSE2)
set_source_files_properties(geometry/triangleMeshAVX.cpp PROPERTIES COMPILE_FLAGS /arch:AVX2)
else()
set_source_files_properties(geometry/triangleMeshSSE.cpp PROPERTIES COMPILE_FLAGS -msse2) # Up to SSE2
set_source_files_properties(geometry/triangleMeshSSE4.cpp PROPERTIES COMPILE_FLAGS -msse4.1) # Up to SSE4_1
set_source_files_properties(geometry/triangleMeshAVX.cpp PROPERTIES COMPILE_FLAGS -mfma) # Includes AVX, AVX2 and FMA
endif()
================================================
FILE: Physics3D/Physics3D.vcxproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{DC20CBAC-AB67-4A0C-BBE2-65DC81DEF289}</ProjectGuid>
<RootNamespace>physics</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>Physics3D</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetName>$(ProjectName)</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetName>$(ProjectName)</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<LanguageStandard>stdcpp17</LanguageStandard>
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<PreprocessorDefinitions>_MBCS;NDEBUG;CATCH_INTERSECTION_ERRORS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<LanguageStandard>stdcpp17</LanguageStandard>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="inertia.cpp" />
<ClCompile Include="part.cpp" />
<ClCompile Include="physical.cpp" />
<ClCompile Include="rigidBody.cpp" />
<ClCompile Include="layer.cpp" />
<ClCompile Include="world.cpp" />
<ClCompile Include="worldPhysics.cpp" />
<ClCompile Include="math\linalg\eigen.cpp" />
<ClCompile Include="math\linalg\trigonometry.cpp" />
<ClCompile Include="geometry\computationBuffer.cpp" />
<ClCompile Include="geometry\convexShapeBuilder.cpp" />
<ClCompile Include="geometry\indexedShape.cpp" />
<ClCompile Include="geometry\genericIntersection.cpp" />
<ClCompile Include="geometry\intersection.cpp" />
<ClCompile Include="geometry\polyhedron.cpp" />
<ClCompile Include="geometry\shape.cpp" />
<ClCompile Include="geometry\shapeBuilder.cpp" />
<ClCompile Include="geometry\shapeClass.cpp" />
<ClCompile Include="geometry\builtinShapeClasses.cpp" />
<ClCompile Include="geometry\shapeCreation.cpp" />
<ClCompile Include="geometry\triangleMesh.cpp" />
<ClCompile Include="geometry\shapeLibrary.cpp" />
<ClCompile Include="geometry\triangleMeshAVX.cpp">
<EnableEnhancedInstructionSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
<EnableEnhancedInstructionSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
</ClCompile>
<ClCompile Include="geometry\triangleMeshSSE.cpp">
<EnableEnhancedInstructionSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<EnableEnhancedInstructionSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
</ClCompile>
<ClCompile Include="geometry\triangleMeshSSE4.cpp">
<EnableEnhancedInstructionSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<EnableEnhancedInstructionSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
</ClCompile>
<ClCompile Include="datastructures\aligned_alloc.cpp" />
<ClCompile Include="boundstree\boundsTree.cpp" />
<ClCompile Include="boundstree\filters\visibilityFilter.cpp" />
<ClCompile Include="softlinks\alignmentLink.cpp" />
<ClCompile Include="softlinks\elasticLink.cpp" />
<ClCompile Include="softlinks\magneticLink.cpp" />
<ClCompile Include="softlinks\softLink.cpp" />
<ClCompile Include="softlinks\springLink.cpp" />
<ClCompile Include="constraints\constraint.cpp" />
<ClCompile Include="constraints\ballConstraint.cpp" />
<ClCompile Include="constraints\hingeConstraint.cpp" />
<ClCompile Include="constraints\barConstraint.cpp" />
<ClCompile Include="constraints\constraintGroup.cpp" />
<ClCompile Include="hardconstraints\hardConstraint.cpp" />
<ClCompile Include="hardconstraints\hardPhysicalConnection.cpp" />
<ClCompile Include="hardconstraints\fixedConstraint.cpp" />
<ClCompile Include="hardconstraints\motorConstraint.cpp" />
<ClCompile Include="hardconstraints\controller\sineWaveController.cpp" />
<ClCompile Include="externalforces\externalForce.cpp" />
<ClCompile Include="externalforces\directionalGravity.cpp" />
<ClCompile Include="externalforces\magnetForce.cpp" />
<ClCompile Include="threading\upgradeableMutex.cpp" />
<ClCompile Include="threading\physicsThread.cpp" />
<ClCompile Include="misc\cpuid.cpp" />
<ClCompile Include="misc\physicsProfiler.cpp" />
<ClCompile Include="misc\validityHelper.cpp" />
<ClCompile Include="misc\debug.cpp" />
<ClCompile Include="misc\serialization\serializeBasicTypes.cpp" />
<ClCompile Include="misc\serialization\serialization.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="layer.h" />
<ClInclude Include="inertia.h" />
<ClInclude Include="motion.h" />
<ClInclude Include="part.h" />
<ClInclude Include="physical.h" />
<ClInclude Include="relativeMotion.h" />
<ClInclude Include="rigidBody.h" />
<ClInclude Include="worldPhysics.h" />
<ClInclude Include="world.h" />
<ClInclude Include="worldIteration.h" />
<ClInclude Include="colissionBuffer.h" />
<ClInclude Include="math\boundingBox.h" />
<ClInclude Include="math\bounds.h" />
<ClInclude Include="math\cframe.h" />
<ClInclude Include="math\constants.h" />
<ClInclude Include="math\fix.h" />
<ClInclude Include="math\globalCFrame.h" />
<ClInclude Include="math\globalTransform.h" />
<ClInclude Include="math\mathUtil.h" />
<ClInclude Include="math\position.h" />
<ClInclude Include="math\taylorExpansion.h" />
<ClInclude Include="math\predefinedTaylorExpansions.h" />
<ClInclude Include="math\rotation.h" />
<ClInclude Include="math\transform.h" />
<ClInclude Include="math\utils.h" />
<ClInclude Include="math\ray.h" />
<ClInclude Include="math\linalg\commonMatrices.h" />
<ClInclude Include="math\linalg\eigen.h" />
<ClInclude Include="math\linalg\largeMatrix.h" />
<ClInclude Include="math\linalg\largeMatrixAlgorithms.h" />
<ClInclude Include="math\linalg\vec.h" />
<ClInclude Include="math\linalg\mat.h" />
<ClInclude Include="math\linalg\quat.h" />
<ClInclude Include="math\linalg\trigonometry.h" />
<ClInclude Include="geometry\scalableInertialMatrix.h" />
<ClInclude Include="geometry\computationBuffer.h" />
<ClInclude Include="geometry\convexShapeBuilder.h" />
<ClInclude Include="geometry\genericCollidable.h" />
<ClInclude Include="geometry\indexedShape.h" />
<ClInclude Include="geometry\genericIntersection.h" />
<ClInclude Include="geometry\shapeCreation.h" />
<ClInclude Include="geometry\triangleMesh.h" />
<ClInclude Include="geometry\triangleMeshCommon.h" />
<ClInclude Include="geometry\intersection.h" />
<ClInclude Include="geometry\builtinShapeClasses.h" />
<ClInclude Include="geometry\polyhedron.h" />
<ClInclude Include="geometry\shape.h" />
<ClInclude Include="geometry\shapeBuilder.h" />
<ClInclude Include="geometry\shapeClass.h" />
<ClInclude Include="geometry\shapeLibrary.h" />
<ClInclude Include="datastructures\alignedPtr.h" />
<ClInclude Include="datastructures\buffers.h" />
<ClInclude Include="datastructures\iteratorEnd.h" />
<ClInclude Include="datastructures\iteratorFactory.h" />
<ClInclude Include="datastructures\monotonicTree.h" />
<ClInclude Include="datastructures\compactPtrDataPair.h" />
<ClInclude Include="datastructures\sharedArray.h" />
<ClInclude Include="datastructures\uniqueArrayPtr.h" />
<ClInclude Include="datastructures\unmanagedArray.h" />
<ClInclude Include="datastructures\unorderedVector.h" />
<ClInclude Include="datastructures\smartPointers.h" />
<ClInclude Include="datastructures\aligned_alloc.h" />
<ClInclude Include="datastructures\parallelArray.h" />
<ClInclude Include="boundstree\boundsTree.h" />
<ClInclude Include="boundstree\filters\outOfBoundsFilter.h" />
<ClInclude Include="boundstree\filters\rayIntersectsBoundsFilter.h" />
<ClInclude Include="boundstree\filters\visibilityFilter.h" />
<ClInclude Include="softlinks\softLink.h" />
<ClInclude Include="softlinks\springLink.h" />
<ClInclude Include="softlinks\alignmentLink.h" />
<ClInclude Include="softlinks\elasticLink.h" />
<ClInclude Include="softlinks\magneticLink.h" />
<ClInclude Include="constraints\constraint.h" />
<ClInclude Include="constraints\constraintImpl.h" />
<ClInclude Include="constraints\ballConstraint.h" />
<ClInclude Include="constraints\hingeConstraint.h" />
<ClInclude Include="constraints\barConstraint.h" />
<ClInclude Include="constraints\constraintGroup.h" />
<ClInclude Include="hardconstraints\hardConstraint.h" />
<ClInclude Include="hardconstraints\constraintTemplates.h" />
<ClInclude Include="hardconstraints\fixedConstraint.h" />
<ClInclude Include="hardconstraints\hardPhysicalConnection.h" />
<ClInclude Include="hardconstraints\motorConstraint.h" />
<ClInclude Include="hardconstraints\sinusoidalPistonConstraint.h" />
<ClInclude Include="hardconstraints\controller\constController.h" />
<ClInclude Include="hardconstraints\controller\sineWaveController.h" />
<ClInclude Include="externalforces\externalForce.h" />
<ClInclude Include="externalforces\directionalGravity.h" />
<ClInclude Include="externalforces\magnetForce.h" />
<ClInclude Include="threading\sharedLockGuard.h" />
<ClInclude Include="threading\threadPool.h" />
<ClInclude Include="threading\upgradeableMutex.h" />
<ClInclude Include="threading\physicsThread.h" />
<ClInclude Include="misc\debug.h" />
<ClInclude Include="misc\unreachable.h" />
<ClInclude Include="misc\toString.h" />
<ClInclude Include="misc\validityHelper.h" />
<ClInclude Include="misc\catchable_assert.h" />
<ClInclude Include="misc\cpuid.h" />
<ClInclude Include="misc\physicsProfiler.h" />
<ClInclude Include="misc\profiling.h" />
<ClInclude Include="misc\serialization\dynamicSerialize.h" />
<ClInclude Include="misc\serialization\serializeBasicTypes.h" />
<ClInclude Include="misc\serialization\sharedObjectSerializer.h" />
<ClInclude Include="misc\serialization\serialization.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
================================================
FILE: Physics3D/boundstree/boundsTree.cpp
================================================
#include "boundsTree.h"
#include "../datastructures/aligned_alloc.h"
namespace P3D {
// naive implementation, to be optimized
BoundsTemplate<float> TrunkSIMDHelperFallback::getTotalBounds(const TreeTrunk& trunk, int upTo) {
assert(upTo >= 1 && upTo <= BRANCH_FACTOR);
BoundsTemplate<float> totalBounds = trunk.getBoundsOfSubNode(0);
for(int i = 1; i < upTo; i++) {
totalBounds = unionOfBounds(totalBounds, trunk.getBoundsOfSubNode(i));
}
return totalBounds;
}
// naive implementation, to be optimized
BoundsTemplate<float> TrunkSIMDHelperFallback::getTotalBoundsWithout(const TreeTrunk& trunk, int upTo, int without) {
assert(upTo >= 2 && upTo <= BRANCH_FACTOR); // size must be at least 2, can't compute otherwise
assert(without >= 0 && without < BRANCH_FACTOR);
if(without == 0) {
BoundsTemplate<float> totalBounds = trunk.getBoundsOfSubNode(1);
for(int i = 2; i < upTo; i++) {
totalBounds = unionOfBounds(totalBounds, trunk.getBoundsOfSubNode(i));
}
return totalBounds;
} else {
BoundsTemplate<float> totalBounds = trunk.getBoundsOfSubNode(0);
for(int i = 1; i < upTo; i++) {
if(i == without) continue;
totalBounds = unionOfBounds(totalBounds, trunk.getBoundsOfSubNode(i));
}
return totalBounds;
}
}
BoundsArray<BRANCH_FACTOR> TrunkSIMDHelperFallback::getAllTotalBoundsWithout(const TreeTrunk& trunk, int upTo) {
assert(upTo >= 2 && upTo <= BRANCH_FACTOR); // size must be at least 2, can't compute otherwise
BoundsArray<BRANCH_FACTOR> result;
{
BoundsTemplate<float> totalBounds0 = trunk.getBoundsOfSubNode(1);
for(int i = 2; i < upTo; i++) {
totalBounds0 = unionOfBounds(totalBounds0, trunk.getBoundsOfSubNode(i));
}
result.setBounds(0, totalBounds0);
}
for(int without = 1; without < upTo; without++) {
BoundsTemplate<float> totalBounds = trunk.getBoundsOfSubNode(0);
for(int i = 2; i < upTo; i++) {
if(i == without) continue;
totalBounds = unionOfBounds(totalBounds, trunk.getBoundsOfSubNode(i));
}
result.setBounds(without, totalBounds);
}
return result;
}
std::array<bool, BRANCH_FACTOR> TrunkSIMDHelperFallback::getAllContainsBounds(const TreeTrunk& trunk, const BoundsTemplate<float>& boundsToContain) {
std::array<bool, BRANCH_FACTOR> contained;
for(int i = 0; i < BRANCH_FACTOR; i++) {
BoundsTemplate<float> subNodeBounds = trunk.getBoundsOfSubNode(i);
contained[i] = subNodeBounds.contains(boundsToContain);
}
return contained;
}
std::array<float, BRANCH_FACTOR> TrunkSIMDHelperFallback::computeAllCosts(const TreeTrunk& trunk) {
std::array<float, BRANCH_FACTOR> costs;
for(int i = 0; i < BRANCH_FACTOR; i++) {
BoundsTemplate<float> subNodeBounds = trunk.getBoundsOfSubNode(i);
costs[i] = computeCost(subNodeBounds);
}
return costs;
}
std::array<float, BRANCH_FACTOR> TrunkSIMDHelperFallback::computeAllCombinationCosts(const BoundsArray<BRANCH_FACTOR>& boundsArr, const BoundsTemplate<float>& boundsExtention) {
std::array<float, BRANCH_FACTOR> costs;
for(int i = 0; i < BRANCH_FACTOR; i++) {
BoundsTemplate<float> subNodeBounds = boundsArr.getBounds(i);
costs[i] = computeCost(unionOfBounds(boundsExtention, subNodeBounds));
}
return costs;
}
std::pair<int, int> TrunkSIMDHelperFallback::computeFurthestObjects(const BoundsArray<BRANCH_FACTOR * 2>& boundsArray, int size) {
std::pair<int, int> furthestObjects{0, 1};
float biggestCost = -std::numeric_limits<float>::infinity();
for(int i = 0; i < size - 1; i++) {
BoundsTemplate<float> iBounds = boundsArray.getBounds(i);
for(int j = i + 1; j < size; j++) {
BoundsTemplate<float> jBounds = boundsArray.getBounds(j);
float cost = computeCost(unionOfBounds(iBounds, jBounds));
if(cost > biggestCost) {
biggestCost = cost;
furthestObjects.first = i;
furthestObjects.second = j;
}
}
}
return furthestObjects;
}
int TrunkSIMDHelperFallback::getLowestCombinationCost(const TreeTrunk& trunk, const BoundsTemplate<float>& boundsExtention, int nodeSize) {
std::array<float, BRANCH_FACTOR> costs = TrunkSIMDHelperFallback::computeAllCombinationCosts(trunk.subNodeBounds, boundsExtention);
float bestCost = costs[0];
int bestIndex = 0;
for(int i = 1; i < nodeSize; i++) {
if(costs[i] < bestCost) {
bestIndex = i;
bestCost = costs[i];
}
}
return bestIndex;
}
std::array<bool, BRANCH_FACTOR> TrunkSIMDHelperFallback::computeOverlapsWith(const TreeTrunk& trunk, int trunkSize, const BoundsTemplate<float>& bounds) {
std::array<bool, BRANCH_FACTOR> result;
for(int i = 0; i < trunkSize; i++) {
result[i] = intersects(trunk.getBoundsOfSubNode(i), bounds);
}
return result;
}
OverlapMatrix TrunkSIMDHelperFallback::computeBoundsOverlapMatrix(const TreeTrunk& trunkA, int trunkASize, const TreeTrunk& trunkB, int trunkBSize) {
OverlapMatrix result;
for(int a = 0; a < trunkASize; a++) {
BoundsTemplate<float> aBounds = trunkA.getBoundsOfSubNode(a);
for(int b = 0; b < trunkBSize; b++) {
BoundsTemplate<float> bBounds = trunkB.getBoundsOfSubNode(b);
result[a][b] = intersects(aBounds, bBounds);
}
}
return result;
}
OverlapMatrix TrunkSIMDHelperFallback::computeInternalBoundsOverlapMatrix(const TreeTrunk& trunk, int trunkSize) {
OverlapMatrix result;
for(int a = 0; a < trunkSize; a++) {
BoundsTemplate<float> aBounds = trunk.getBoundsOfSubNode(a);
for(int b = a+1; b < trunkSize; b++) {
BoundsTemplate<float> bBounds = trunk.getBoundsOfSubNode(b);
result[a][b] = intersects(aBounds, bBounds);
}
}
return result;
}
std::array<float, BRANCH_FACTOR> TrunkSIMDHelperFallback::computeAllExtentionCosts(const TreeTrunk& trunk, int trunkSize, const BoundsTemplate<float>& extraBounds) {
std::array<float, BRANCH_FACTOR> resultingCosts;
for(int i = 0; i < trunkSize; i++) {
resultingCosts[i] = computeAdditionCost(trunk.getBoundsOfSubNode(i), extraBounds);
}
return resultingCosts;
}
int TrunkSIMDHelperFallback::transferNodes(TreeTrunk& srcTrunk, int srcTrunkStart, int srcTrunkEnd, TreeTrunk& destTrunk, int destTrunkSize) {
for(int i = srcTrunkStart; i < srcTrunkEnd; i++) {
destTrunk.setSubNode(destTrunkSize, std::move(srcTrunk.subNodes[i]), srcTrunk.getBoundsOfSubNode(i));
destTrunkSize++;
}
return destTrunkSize;
}
BoundsArray<BRANCH_FACTOR * 2> TrunkSIMDHelperFallback::combineBoundsArrays(const TreeTrunk& trunkA, int trunkASize, const TreeTrunk& trunkB, int trunkBSize) {
BoundsArray<BRANCH_FACTOR * 2> result;
for(int i = 0; i < trunkASize; i++) {
result.setBounds(i, trunkA.getBoundsOfSubNode(i));
}
for(int i = 0; i < trunkBSize; i++) {
result.setBounds(trunkASize + i, trunkB.getBoundsOfSubNode(i));
}
return result;
}
// returns true if modified
bool TrunkSIMDHelperFallback::exchangeNodesBetween(TreeTrunk& trunkA, int& trunkASize, TreeTrunk& trunkB, int& trunkBSize) {
int totalSize = trunkASize + trunkBSize;
// if this is not the case, we could've just merged the nodes, this is handled in another function
// if totalSize was BRANCH_FACTOR + 1 we could've moved all but one node from one trunk to the other, also handled elsewhere
assert(totalSize >= BRANCH_FACTOR + 2);
BoundsArray<BRANCH_FACTOR * 2> allBounds = TrunkSIMDHelperFallback::combineBoundsArrays(trunkA, trunkASize, trunkB, trunkBSize);
std::pair<int, int> furthestObjects = TrunkSIMDHelperFallback::computeFurthestObjects(allBounds, totalSize);
BoundsTemplate<float> aBounds = allBounds.getBounds(furthestObjects.first);
BoundsTemplate<float> bBounds = allBounds.getBounds(furthestObjects.second);
int aResultSize = 0;
int bResultSize = 0;
int aResult[BRANCH_FACTOR * 2];
int bResult[BRANCH_FACTOR * 2];
// positive if costA < costB
float allDeltaCosts[BRANCH_FACTOR * 2];
for(int i = 0; i < totalSize; i++) {
BoundsTemplate<float> bounds = allBounds.getBounds(i);
float costA = computeCost(unionOfBounds(aBounds, bounds));
float costB = computeCost(unionOfBounds(bBounds, bounds));
allDeltaCosts[i] = costB - costA;
}
for(int i = 0; i < totalSize; i++) {
if(allDeltaCosts[i] >= 0.0) {
aResult[aResultSize++] = i;
} else {
bResult[bResultSize++] = i;
}
}
if(aResultSize > BRANCH_FACTOR) {
// move least costly elements from a to b (least costly cost is closest to 0)
do {
int worstIndex = 0;
float worstCost = allDeltaCosts[aResult[0]];
for(int i = 1; i < aResultSize; i++) {
float cost = allDeltaCosts[aResult[i]];
if(cost < worstCost) {
worstIndex = i;
worstCost = cost;
}
}
bResult[bResultSize++] = aResult[worstIndex];
aResult[worstIndex] = aResult[--aResultSize];
} while(aResultSize > BRANCH_FACTOR);
} else if(bResultSize > BRANCH_FACTOR) {
// move least costly elements from b to a (least costly cost is closest to 0)
do {
int worstIndex = 0;
float worstCost = allDeltaCosts[bResult[0]];
for(int i = 1; i < bResultSize; i++) {
float cost = allDeltaCosts[bResult[i]];
if(cost > worstCost) { // these costs are all negative
worstIndex = i;
worstCost = cost;
}
}
aResult[aResultSize++] = bResult[worstIndex];
bResult[worstIndex] = bResult[--bResultSize];
} while(bResultSize > BRANCH_FACTOR);
}
assert(aResultSize + bResultSize == totalSize);
assert(aResultSize <= BRANCH_FACTOR && bResultSize <= BRANCH_FACTOR);
assert(aResultSize >= 2 && bResultSize >= 2); // Guaranteed by totalSize >= BRANCH_FACTOR + 2 && aResultSize <= BRANCH_FACTOR && bResultSize <= BRANCH_FACTOR
// checks to see if a change needs to be made
bool a0ComesFromA = aResult[0] < trunkASize;
bool b0ComesFromA = bResult[0] < trunkASize;
if(a0ComesFromA != b0ComesFromA) {// they differ in origin
for(int i = 1; i < aResultSize; i++) {
bool comesFromA = aResult[i] < trunkASize;
if(comesFromA != a0ComesFromA) {
goto wasChanged;
}
}
for(int i = 1; i < bResultSize; i++) {
bool comesFromA = bResult[i] < trunkASize;
if(comesFromA != b0ComesFromA) {
goto wasChanged;
}
}
return false;
}
wasChanged:;
TreeNodeRef allSubNodes[BRANCH_FACTOR * 2];
for(int i = 0; i < trunkASize; i++) {
allSubNodes[i] = std::move(trunkA.subNodes[i]);
}
for(int i = 0; i < trunkBSize; i++) {
allSubNodes[i+trunkASize] = std::move(trunkB.subNodes[i]);
}
for(int i = 0; i < aResultSize; i++) {
int from = aResult[i];
trunkA.setSubNode(i, std::move(allSubNodes[from]), allBounds.getBounds(from));
}
for(int i = 0; i < bResultSize; i++) {
int from = bResult[i];
trunkB.setSubNode(i, std::move(allSubNodes[from]), allBounds.getBounds(from));
}
trunkASize = aResultSize;
trunkBSize = bResultSize;
return true;
}
// returns the new size of this node, to be applied to the caller
int addRecursive(TrunkAllocator& allocator, TreeTrunk& curTrunk, int curTrunkSize, TreeNodeRef&& newNode, const BoundsTemplate<float>& bounds) {
assert(curTrunkSize >= 0 && curTrunkSize <= BRANCH_FACTOR);
if(curTrunkSize == BRANCH_FACTOR) {
int chosenNode = TrunkSIMDHelperFallback::getLowestCombinationCost(curTrunk, bounds, curTrunkSize);
TreeNodeRef& chosen = curTrunk.subNodes[chosenNode];
BoundsTemplate<float> oldSubNodeBounds = curTrunk.getBoundsOfSubNode(chosenNode);
// can be inserted into the trunkNode
if(chosen.isTrunkNode() && !chosen.isGroupHead()) {
int newSize = addRecursive(allocator, chosen.asTrunk(), chosen.getTrunkSize(), std::move(newNode), bounds);
chosen.setTrunkSize(newSize);
} else {
TreeTrunk* newTrunk = allocator.allocTrunk();
newTrunk->setSubNode(0, std::move(chosen), oldSubNodeBounds);
newTrunk->setSubNode(1, std::move(newNode), bounds);
chosen = TreeNodeRef(newTrunk, 2, false);
}
curTrunk.setBoundsOfSubNode(chosenNode, unionOfBounds(oldSubNodeBounds, bounds));
return BRANCH_FACTOR;
} else {
curTrunk.setSubNode(curTrunkSize, std::move(newNode), bounds);
return curTrunkSize + 1;
}
}
bool containsObjectRecursive(const TreeTrunk& trunk, int trunkSize, const void* object, const BoundsTemplate<float>& bounds) {
assert(trunkSize >= 0 && trunkSize <= BRANCH_FACTOR);
std::array<bool, BRANCH_FACTOR> couldContain = TrunkSIMDHelperFallback::getAllContainsBounds(trunk, bounds);
for(int i = 0; i < trunkSize; i++) {
if(!couldContain[i]) continue;
const TreeNodeRef& subNode = trunk.subNodes[i];
if(subNode.isTrunkNode()) {
if(containsObjectRecursive(subNode.asTrunk(), subNode.getTrunkSize(), object, bounds)) {
return true;
}
} else {
if(subNode.asObject() == object) {
return true;
}
}
}
return false;
}
// returns new trunkSize if removed, -1 if not removed
int removeRecursive(TrunkAllocator& allocator, TreeTrunk& curTrunk, int curTrunkSize, const void* objectToRemove, const BoundsTemplate<float>& bounds) {
assert(curTrunkSize >= 0 && curTrunkSize <= BRANCH_FACTOR);
std::array<bool, BRANCH_FACTOR> couldContain = TrunkSIMDHelperFallback::getAllContainsBounds(curTrunk, bounds);
for(int i = 0; i < curTrunkSize; i++) {
if(!couldContain[i]) continue;
TreeNodeRef& subNode = curTrunk.subNodes[i];
if(subNode.isTrunkNode()) {
TreeTrunk& subNodeTrunk = subNode.asTrunk();
assert(subNode.getTrunkSize() >= 2);
int newSubNodeTrunkSize = removeRecursive(allocator, subNodeTrunk, subNode.getTrunkSize(), objectToRemove, bounds);
assert(newSubNodeTrunkSize >= 1 || newSubNodeTrunkSize == -1);
if(newSubNodeTrunkSize != -1) {
if(newSubNodeTrunkSize == 1) {
// remove reduntant trunk
bool wasGroupHead = subNode.isGroupHead();
subNode = std::move(subNodeTrunk.subNodes[0]);
curTrunk.setBoundsOfSubNode(i, subNodeTrunk.getBoundsOfSubNode(0));
if(wasGroupHead && subNode.isTrunkNode()) {
subNode.makeGroupHead(); // in the rare case that it removes Z in a node that is a group like this: GH[TN[X,Y],Z]. Without this the grouping would be lost
}
allocator.freeTrunk(&subNodeTrunk);
} else {
curTrunk.setBoundsOfSubNode(i, TrunkSIMDHelperFallback::getTotalBounds(subNodeTrunk, newSubNodeTrunkSize));
subNode.setTrunkSize(newSubNodeTrunkSize);
}
return curTrunkSize;
}
} else {
if(subNode.asObject() == objectToRemove) {
curTrunk.moveSubNode(curTrunkSize - 1, i);
return curTrunkSize - 1;
}
}
}
return -1;
}
struct TreeGrab {
int resultingGroupSize;
TreeNodeRef nodeRef;
BoundsTemplate<float> nodeBounds;
TreeGrab() : resultingGroupSize(-1) {}
TreeGrab(int resultingGroupSize, TreeNodeRef&& nodeRef, const BoundsTemplate<float>& nodeBounds) :
resultingGroupSize(resultingGroupSize),
nodeRef(std::move(nodeRef)),
nodeBounds(nodeBounds) {}
};
// returns new trunkSize if removed, -1 if not removed
static TreeGrab grabGroupRecursive(TrunkAllocator& allocator, TreeTrunk& curTrunk, int curTrunkSize, const void* groupRepresentative, const BoundsTemplate<float>& representativeBounds) {
assert(curTrunkSize >= 0 && curTrunkSize <= BRANCH_FACTOR);
std::array<bool, BRANCH_FACTOR> couldContain = TrunkSIMDHelperFallback::getAllContainsBounds(curTrunk, representativeBounds);
for(int i = 0; i < curTrunkSize; i++) {
if(!couldContain[i]) continue;
TreeNodeRef& subNode = curTrunk.subNodes[i];
if(subNode.isTrunkNode()) {
TreeTrunk& subNodeTrunk = subNode.asTrunk();
size_t trunkSize = subNode.getTrunkSize();
assert(trunkSize >= 2);
if(subNode.isGroupHead()) {
if(containsObjectRecursive(subNodeTrunk, trunkSize, groupRepresentative, representativeBounds)) {
// found group, now remove it
TreeNodeRef subNodeCopy = std::move(subNode);
curTrunk.moveSubNode(curTrunkSize - 1, i);
return TreeGrab(curTrunkSize - 1, std::move(subNodeCopy), curTrunk.getBoundsOfSubNode(i));
}
} else {
// try
TreeGrab recursiveResult = grabGroupRecursive(allocator, subNodeTrunk, subNode.getTrunkSize(), groupRepresentative, representativeBounds);
int newSubNodeTrunkSize = recursiveResult.resultingGroupSize;
assert(newSubNodeTrunkSize >= 1 || newSubNodeTrunkSize == -1);
if(newSubNodeTrunkSize != -1) {
if(newSubNodeTrunkSize == 1) {
// remove reduntant trunk
curTrunk.setSubNode(i, std::move(subNodeTrunk.subNodes[0]), subNodeTrunk.getBoundsOfSubNode(0));
allocator.freeTrunk(&subNodeTrunk);
} else {
curTrunk.setBoundsOfSubNode(i, TrunkSIMDHelperFallback::getTotalBounds(subNodeTrunk, newSubNodeTrunkSize));
subNode.setTrunkSize(newSubNodeTrunkSize);
}
recursiveResult.resultingGroupSize = curTrunkSize;
return recursiveResult;
}
}
} else {
if(subNode.asObject() == groupRepresentative) {
TreeNodeRef subNodeCopy = std::move(subNode);
BoundsTemplate<float> subNodeBounds = curTrunk.getBoundsOfSubNode(i);
curTrunk.moveSubNode(curTrunkSize - 1, i);
return TreeGrab(curTrunkSize - 1, std::move(subNodeCopy), subNodeBounds);
}
}
}
return TreeGrab();
}
const TreeNodeRef* getGroupRecursive(const TreeTrunk& curTrunk, int curTrunkSize, const void* groupRepresentative, const BoundsTemplate<float>& representativeBounds) {
assert(curTrunkSize >= 0 && curTrunkSize <= BRANCH_FACTOR);
std::array<bool, BRANCH_FACTOR> couldContain = TrunkSIMDHelperFallback::getAllContainsBounds(curTrunk, representativeBounds);
for(int i = 0; i < curTrunkSize; i++) {
if(!couldContain[i]) continue;
const TreeNodeRef& subNode = curTrunk.subNodes[i];
if(subNode.isTrunkNode()) {
const TreeTrunk& subNodeTrunk = subNode.asTrunk();
size_t subTrunkSize = subNode.getTrunkSize();
assert(subTrunkSize >= 2);
if(subNode.isGroupHead()) {
if(containsObjectRecursive(subNodeTrunk, subTrunkSize, groupRepresentative, representativeBounds)) {
return &subNode;
}
} else {
const TreeNodeRef* recursiveFound = getGroupRecursive(subNodeTrunk, subTrunkSize, groupRepresentative, representativeBounds);
if(recursiveFound != nullptr) {
return recursiveFound;
}
}
} else {
if(subNode.asObject() == groupRepresentative) {
return &subNode;
}
}
}
return nullptr;
}
// also frees starting trunk
static void freeTrunksRecursive(TrunkAllocator& alloc, TreeTrunk& curTrunk, int curTrunkSize) {
for(int i = 0; i < curTrunkSize; i++) {
TreeNodeRef& subNode = curTrunk.subNodes[i];
if(subNode.isTrunkNode()) {
TreeTrunk& subTrunk = subNode.asTrunk();
freeTrunksRecursive(alloc, subTrunk, subNode.getTrunkSize());
}
}
alloc.freeTrunk(&curTrunk);
}
// expects a function of the form void(void* object, const BoundsTemplate<float>& bounds)
template<typename Func>
static void forEachRecurseWithBounds(const TreeTrunk& curTrunk, int curTrunkSize, const Func& func) {
for(int i = 0; i < curTrunkSize; i++) {
const TreeNodeRef& subNode = curTrunk.subNodes[i];
if(subNode.isTrunkNode()) {
forEachRecurseWithBounds(subNode.asTrunk(), subNode.getTrunkSize(), func);
} else {
func(subNode.asObject(), curTrunk.getBoundsOfSubNode(i));
}
}
}
// returns true if the group that is inserted into is found
// deletes all trunknodes of the destroyed group with the provided allocator
static bool insertGroupIntoGroup(TrunkAllocator& sourceAlloc, TrunkAllocator& destinationAlloc, TreeTrunk& baseTrunk, int baseTrunkSize, const void* groupToAddToRep, const BoundsTemplate<float>& groupToAddToRepBounds, TreeNodeRef&& groupToDestroy, const BoundsTemplate<float>& groupToDestroyBounds) {
bool groupWasFound = modifyGroupRecursive(destinationAlloc, baseTrunk, baseTrunkSize, groupToAddToRep, groupToAddToRepBounds, [&sourceAlloc, &destinationAlloc, &groupToDestroy, &groupToDestroyBounds](TreeNodeRef& group, const BoundsTemplate<float>& groupBounds) {
TreeTrunk* trunk;
int trunkSize;
if(group.isLeafNode()) {
trunk = destinationAlloc.allocTrunk();
trunk->setSubNode(0, std::move(group), groupBounds);
trunkSize = 1;
} else {
trunk = &group.asTrunk();
trunkSize = group.getTrunkSize();
}
if(groupToDestroy.isTrunkNode()) {
forEachRecurseWithBounds(groupToDestroy.asTrunk(), groupToDestroy.getTrunkSize(), [&](void* object, const BoundsTemplate<float>& bounds) {
trunkSize = addRecursive(destinationAlloc, *trunk, trunkSize, TreeNodeRef(object), bounds);
});
} else {
trunkSize = addRecursive(destinationAlloc, *trunk, trunkSize, TreeNodeRef(groupToDestroy.asObject()), groupToDestroyBounds);
}
group = TreeNodeRef(trunk, trunkSize, true);
if(groupToDestroy.isTrunkNode()) {
TreeTrunk& destroyTrunk = groupToDestroy.asTrunk();
freeTrunksRecursive(sourceAlloc, destroyTrunk, groupToDestroy.getTrunkSize());
}
return TrunkSIMDHelperFallback::getTotalBounds(*trunk, trunkSize);
});
return groupWasFound;
}
TrunkAllocator::TrunkAllocator() : allocationCount(0) {}
TrunkAllocator::~TrunkAllocator() {
assert(this->allocationCount == 0);
}
TrunkAllocator::TrunkAllocator(TrunkAllocator&& other) noexcept : allocationCount(other.allocationCount) {
other.allocationCount = 0;
}
TrunkAllocator& TrunkAllocator::operator=(TrunkAllocator&& other) noexcept {
std::swap(this->allocationCount, other.allocationCount);
return *this;
}
TreeTrunk* TrunkAllocator::allocTrunk() {
this->allocationCount++;
std::cout << "allocTrunk " << this->allocationCount << std::endl;
return static_cast<TreeTrunk*>(aligned_malloc(sizeof(TreeTrunk), alignof(TreeTrunk)));
}
void TrunkAllocator::freeTrunk(TreeTrunk* trunk) {
this->allocationCount--;
std::cout << "freeTrunk " << this->allocationCount << std::endl;
aligned_free(trunk);
}
void TrunkAllocator::freeAllTrunks(TreeTrunk& baseTrunk, int baseTrunkSize) {
for(int i = 0; i < baseTrunkSize; i++) {
TreeNodeRef& subNode = baseTrunk.subNodes[i];
if(subNode.isTrunkNode()) {
freeTrunksRecursive(*this, subNode.asTrunk(), subNode.getTrunkSize());
}
}
}
BoundsTreePrototype::BoundsTreePrototype() : baseTrunk(), baseTrunkSize(0) {}
BoundsTreePrototype::~BoundsTreePrototype() {
this->clear();
}
void BoundsTreePrototype::addGroupTrunk(TreeTrunk* newTrunk, int newTrunkSize) {
this->baseTrunkSize = addRecursive(allocator, baseTrunk, baseTrunkSize, TreeNodeRef(newTrunk, newTrunkSize, true), TrunkSIMDHelperFallback::getTotalBounds(*newTrunk, newTrunkSize));
}
void BoundsTreePrototype::add(void* newObject, const BoundsTemplate<float>& bounds) {
this->baseTrunkSize = addRecursive(allocator, baseTrunk, baseTrunkSize, TreeNodeRef(newObject), bounds);
}
void BoundsTreePrototype::addToGroup(void* newObject, const BoundsTemplate<float>& newObjectBounds, const void* groupRepresentative, const BoundsTemplate<float>& groupRepBounds) {
bool foundGroup = modifyGroupRecursive(allocator, baseTrunk, baseTrunkSize, groupRepresentative, groupRepBounds, [this, newObject, &newObjectBounds](TreeNodeRef& groupNode, const BoundsTemplate<float>& groupNodeBounds) {
assert(groupNode.isGroupHeadOrLeaf());
if(groupNode.isTrunkNode()) {
TreeTrunk& groupTrunk = groupNode.asTrunk();
int resultingSize = addRecursive(allocator, groupTrunk, groupNode.getTrunkSize(), TreeNodeRef(newObject), newObjectBounds);
groupNode.setTrunkSize(resultingSize);
return TrunkSIMDHelperFallback::getTotalBounds(groupTrunk, resultingSize);
} else {
TreeTrunk* newTrunkNode = allocator.allocTrunk();
newTrunkNode->setSubNode(0, std::move(groupNode), groupNodeBounds);
newTrunkNode->setSubNode(1, TreeNodeRef(newObject), newObjectBounds);
groupNode = TreeNodeRef(newTrunkNode, 2, true);
return TrunkSIMDHelperFallback::getTotalBounds(*newTrunkNode, 2);
}
});
if(!foundGroup) {
throw "Group not found!";
}
}
void BoundsTreePrototype::mergeGroups(const void* groupRepA, const BoundsTemplate<float>& repABounds, const void* groupRepB, const BoundsTemplate<float>& repBBounds) {
TreeGrab grabbed = grabGroupRecursive(this->allocator, this->baseTrunk, this->baseTrunkSize, groupRepA, repABounds);
if(grabbed.resultingGroupSize == -1) {
throw "groupRepA not found!";
}
this->baseTrunkSize = grabbed.resultingGroupSize;
bool groupBWasFound = insertGroupIntoGroup(this->allocator, this->allocator, this->baseTrunk, this->baseTrunkSize, groupRepB, repBBounds, std::move(grabbed.nodeRef), grabbed.nodeBounds);
if(!groupBWasFound) {
throw "groupRepB not found!";
}
}
void BoundsTreePrototype::transferGroupTo(const void* groupRep, const BoundsTemplate<float>& groupRepBounds, BoundsTreePrototype& destinationTree) {
TreeGrab grabbed = grabGroupRecursive(this->allocator, this->baseTrunk, this->baseTrunkSize, groupRep, groupRepBounds);
if(grabbed.resultingGroupSize == -1) {
throw "groupRep not found!";
}
this->baseTrunkSize = grabbed.resultingGroupSize;
bool groupBWasFound = addRecursive(destinationTree.allocator, destinationTree.baseTrunk, destinationTree.baseTrunkSize, std::move(grabbed.nodeRef), grabbed.nodeBounds);
assert(groupBWasFound);
}
void BoundsTreePrototype::remove(const void* objectToRemove, const BoundsTemplate<float>& bounds) {
int resultingBaseSize = removeRecursive(allocator, baseTrunk, baseTrunkSize, objectToRemove, bounds);
if(resultingBaseSize != -1) {
this->baseTrunkSize = resultingBaseSize;
} else {
throw "Object not found!";
}
}
bool BoundsTreePrototype::contains(const void* object, const BoundsTemplate<float>& bounds) const {
return containsObjectRecursive(baseTrunk, baseTrunkSize, object, bounds);
}
bool BoundsTreePrototype::groupContains(const void* object, const BoundsTemplate<float>& bounds, const void* groupRep, const BoundsTemplate<float>& groupRepBounds) const {
const TreeNodeRef* groupFound = getGroupRecursive(this->baseTrunk, this->baseTrunkSize, groupRep, groupRepBounds);
if(!groupFound) {
throw "Group not found!";
}
if(groupFound->isTrunkNode()) {
return containsObjectRecursive(groupFound->asTrunk(), groupFound->getTrunkSize(), object, bounds);
} else {
return groupFound->asObject() == object;
}
}
static bool updateObjectBoundsRecurive(TreeTrunk& curTrunk, int curTrunkSize, const void* object, const BoundsTemplate<float>& originalBounds, const BoundsTemplate<float>& newBounds) {
assert(curTrunkSize >= 0 && curTrunkSize <= BRANCH_FACTOR);
std::array<bool, BRANCH_FACTOR> couldContain = TrunkSIMDHelperFallback::getAllContainsBounds(curTrunk, originalBounds);
for(int i = 0; i < curTrunkSize; i++) {
if(!couldContain[i]) continue;
TreeNodeRef& subNode = curTrunk.subNodes[i];
if(subNode.isTrunkNode()) {
TreeTrunk& subTrunk = subNode.asTrunk();
int subTrunkSize = subNode.getTrunkSize();
if(updateObjectBoundsRecurive(subTrunk, subTrunkSize, object, originalBounds, newBounds)) {
curTrunk.setBoundsOfSubNode(i, TrunkSIMDHelperFallback::getTotalBounds(subTrunk, subTrunkSize));
return true;
}
} else {
if(subNode.asObject() == object) {
curTrunk.setBoundsOfSubNode(i, newBounds);
return true;
}
}
}
return false;
}
void BoundsTreePrototype::updateObjectBounds(const void* object, const BoundsTemplate<float>& originalBounds, const BoundsTemplate<float>& newBounds) {
bool wasFound = updateObjectBoundsRecurive(this->baseTrunk, this->baseTrunkSize, object, originalBounds, newBounds);
if(!wasFound) throw "Object was not found!";
}
static bool findAndReplaceObjectRecursive(TreeTrunk& curTrunk, int curTrunkSize, const void* oldObject, void* newObject, const BoundsTemplate<float>& bounds) {
assert(curTrunkSize >= 0 && curTrunkSize <= BRANCH_FACTOR);
std::array<bool, BRANCH_FACTOR> couldContain = TrunkSIMDHelperFallback::getAllContainsBounds(curTrunk, bounds);
for(int i = 0; i < curTrunkSize; i++) {
if(!couldContain[i]) continue;
TreeNodeRef& subNode = curTrunk.subNodes[i];
if(subNode.isTrunkNode()) {
TreeTrunk& subTrunk = subNode.asTrunk();
int subTrunkSize = subNode.getTrunkSize();
if(findAndReplaceObjectRecursive(subTrunk, subTrunkSize, oldObject, newObject, bounds)) {
return true;
}
} else {
if(subNode.asObject() == oldObject) {
subNode.setObject(newObject);
return true;
}
}
}
return false;
}
void BoundsTreePrototype::findAndReplaceObject(const void* oldObject, void* newObject, const BoundsTemplate<float>& bounds) {
bool found = findAndReplaceObjectRecursive(this->baseTrunk, this->baseTrunkSize, oldObject, newObject, bounds);
if(!found) throw "Object to rename not found!";
}
static bool disbandGroupRecursive(TreeTrunk& curTrunk, int curTrunkSize, const void* groupRep, const BoundsTemplate<float>& groupRepBounds) {
assert(curTrunkSize >= 0 && curTrunkSize <= BRANCH_FACTOR);
std::array<bool, BRANCH_FACTOR> couldContain = TrunkSIMDHelperFallback::getAllContainsBounds(curTrunk, groupRepBounds);
for(int i = 0; i < curTrunkSize; i++) {
if(!couldContain[i]) continue;
TreeNodeRef& subNode = curTrunk.subNodes[i];
if(subNode.isTrunkNode()) {
TreeTrunk& subTrunk = subNode.asTrunk();
int subTrunkSize = subNode.getTrunkSize();
if(subNode.isGroupHead()) {
if(containsObjectRecursive(subTrunk, subTrunkSize, groupRep, groupRepBounds)) {
subNode.removeGroupHead();
return true;
}
} else {
if(disbandGroupRecursive(subTrunk, subTrunkSize, groupRep, groupRepBounds)) {
return true;
}
}
} else {
if(subNode.asObject() == groupRep) {
return true;
}
}
}
return false;
}
void BoundsTreePrototype::disbandGroup(const void* groupRep, const BoundsTemplate<float>& groupRepBounds) {
disbandGroupRecursive(this->baseTrunk, this->baseTrunkSize, groupRep, groupRepBounds);
}
static size_t getSizeRecursive(const TreeTrunk& curTrunk, int curTrunkSize) {
size_t total = 0;
for(int i = 0; i < curTrunkSize; i++) {
const TreeNodeRef& subNode = curTrunk.subNodes[i];
if(subNode.isTrunkNode()) {
total += getSizeRecursive(subNode.asTrunk(), subNode.getTrunkSize());
} else {
total++;
}
}
return total;
}
size_t BoundsTreePrototype::size() const {
return getSizeRecursive(baseTrunk, baseTrunkSize);
}
size_t BoundsTreePrototype::groupSize(const void* groupRep, const BoundsTemplate<float>& groupRepBounds) const {
const TreeNodeRef* groupFound = getGroupRecursive(this->baseTrunk, this->baseTrunkSize, groupRep, groupRepBounds);
if(!groupFound) {
throw "Group not found!";
}
if(groupFound->isTrunkNode()) {
return getSizeRecursive(groupFound->asTrunk(), groupFound->getTrunkSize());
} else {
return 1;
}
}
void BoundsTreePrototype::clear() {
this->allocator.freeAllTrunks(this->baseTrunk, this->baseTrunkSize);
this->baseTrunkSize = 0;
}
// means that this trunk and it's subtrunks cannot be improved
static bool isLeafTrunk(TreeTrunk& trunk, int trunkSize) {
for(int subNodeI = 0; subNodeI < trunkSize; subNodeI++) {
TreeNodeRef& subNode = trunk.subNodes[subNodeI];
if(!subNode.isGroupHeadOrLeaf()) return false;
}
return true;
}
static void improveTrunkHorizontal(TrunkAllocator& alloc, TreeTrunk& trunk) {
constexpr int trunkSize = BRANCH_FACTOR; // required by the interface, allows for small SIMD optimizations
assert(!isLeafTrunk(trunk, trunkSize));
// indexed overlaps[i][j] with j >= i+1
OverlapMatrix overlaps = TrunkSIMDHelperFallback::computeInternalBoundsOverlapMatrix(trunk, trunkSize);
for(int subNodeAI = 0; subNodeAI < trunkSize-1; subNodeAI++) {
TreeNodeRef& subNodeA = trunk.subNodes[subNodeAI];
if(subNodeA.isGroupHeadOrLeaf()) continue; // no breaking up groups
TreeTrunk& subTrunkA = subNodeA.asTrunk();
int subTrunkSizeA = subNodeA.getTrunkSize();
for(int subNodeBI = subNodeAI+1; subNodeBI < trunkSize - 1; subNodeBI++) {
TreeNodeRef& subNodeB = trunk.subNodes[subNodeBI];
if(subNodeB.isGroupHeadOrLeaf()) continue; // no breaking up groups
TreeTrunk& subTrunkB = subNodeB.asTrunk();
int subTrunkSizeB = subNodeB.getTrunkSize();
if(!overlaps[subNodeAI][subNodeBI]) continue;
if(subTrunkSizeA + subTrunkSizeB >= BRANCH_FACTOR + 2) {
// if true, this updates subTrunkSizeA and subTrunkSizeB
if(TrunkSIMDHelperFallback::exchangeNodesBetween(subTrunkA, subTrunkSizeA, subTrunkB, subTrunkSizeB)) {
// update treenoderefs
subNodeA.setTrunkSize(subTrunkSizeA);
subNodeB.setTrunkSize(subTrunkSizeB);
trunk.setBoundsOfSubNode(subNodeAI, TrunkSIMDHelperFallback::getTotalBounds(subTrunkA, subTrunkSizeA));
trunk.setBoundsOfSubNode(subNodeBI, TrunkSIMDHelperFallback::getTotalBounds(subTrunkB, subTrunkSizeB));
// just return, changing trunkNodes invalidated overlaps matrix, more improvements can be done in future calls
return;
}
} else {
// can just merge out a Trunk
// move all but first element from B to A
subTrunkSizeA = TrunkSIMDHelperFallback::transferNodes(subTrunkB, 1, subTrunkSizeB, subTrunkA, subTrunkSizeA);
subNodeA.setTrunkSize(subTrunkSizeA);
trunk.setBoundsOfSubNode(subNodeAI, TrunkSIMDHelperFallback::getTotalBounds(subTrunkA, subTrunkSizeA));
trunk.setSubNode(subNodeBI, std::move(subTrunkB.subNodes[0]), subTrunkB.getBoundsOfSubNode(0));
alloc.freeTrunk(&subTrunkB);
// just return, changing trunkNodes invalidated overlaps matrix, more improvements can be done in future calls
return;
}
}
}
}
inline static void swapNodesBetweenTrunks(TreeTrunk& trunkA, int indexInTrunkA, TreeTrunk& trunkB, int indexInTrunkB) {
BoundsTemplate<float> boundsA = trunkA.getBoundsOfSubNode(indexInTrunkA);
BoundsTemplate<float> boundsB = trunkB.getBoundsOfSubNode(indexInTrunkB);
trunkA.setBoundsOfSubNode(indexInTrunkA, boundsB);
trunkB.setBoundsOfSubNode(indexInTrunkB, boundsA);
std::swap(trunkA.subNodes[indexInTrunkA], trunkB.subNodes[indexInTrunkB]);
}
static void improveTrunkVertical(TreeTrunk& trunk) {
constexpr int trunkSize = BRANCH_FACTOR; // required by the interface, allows for small SIMD optimizations
if(isLeafTrunk(trunk, trunkSize)) return; // no improvement possible
std::array<float, BRANCH_FACTOR> allExistingSizes = TrunkSIMDHelperFallback::computeAllCosts(trunk);
int smallestSubNodeI = 0;
float smallestSubNodeSize = allExistingSizes[0];
for(int i = 1; i < trunkSize; i++) {
if(allExistingSizes[i] < smallestSubNodeSize) {
smallestSubNodeSize = allExistingSizes[i];
smallestSubNodeI = i;
}
}
int largestItemSubTrunkI = -1;
int largestItemI = -1;
float largestItemInSubTrunkISize = smallestSubNodeSize; // try to beat this, if we can't then there's no swap
for(int subTrunkI = 0; subTrunkI < trunkSize; subTrunkI++) {
if(subTrunkI == smallestSubNodeI) continue; // the smallest node cannot contain a node larger than itself, also, trying to swap these would store this node in itself, leading to memory leak and objects disappearing
TreeNodeRef& subNode = trunk.subNodes[subTrunkI];
// find a node, and try to swap it with an element from a group
if(subNode.isGroupHeadOrLeaf()) continue;
TreeTrunk& subTrunk = subNode.asTrunk();
int subTrunkSize = subNode.getTrunkSize();
std::array<float, BRANCH_FACTOR> subTrunkSizes = TrunkSIMDHelperFallback::computeAllCosts(subTrunk);
for(int i = 0; i < subTrunkSize; i++) {
if(subTrunkSizes[i] > largestItemInSubTrunkISize) {
largestItemInSubTrunkISize = subTrunkSizes[i];
largestItemSubTrunkI = subTrunkI;
largestItemI = i;
}
}
}
if(largestItemI != -1) {
// an improvement can be made by swapping
TreeTrunk& chosenSubTrunk = trunk.subNodes[largestItemSubTrunkI].asTrunk();
int chosenSubTrunkSize = trunk.subNodes[largestItemSubTrunkI].getTrunkSize();
swapNodesBetweenTrunks(trunk, smallestSubNodeI, chosenSubTrunk, largestItemI);
trunk.setBoundsOfSubNode(largestItemSubTrunkI, TrunkSIMDHelperFallback::getTotalBounds(chosenSubTrunk, chosenSubTrunkSize));
}
}
static int moveElementsOutOfGroup(TrunkAllocator& alloc, TreeTrunk& trunk, int trunkSize) {
assert(!isLeafTrunk(trunk, trunkSize));
if(trunkSize >= BRANCH_FACTOR) return trunkSize;
int freeSlots = BRANCH_FACTOR - trunkSize;
for(int subNodeI = 0; subNodeI < trunkSize; subNodeI++) {
TreeNodeRef& subNode = trunk.subNodes[subNodeI];
// find a node, and try to swap it with an element from a group
if(!subNode.isGroupHeadOrLeaf()) { // no breaking up groups
TreeTrunk& subTrunk = subNode.asTrunk();
int subTrunkSize = subNode.getTrunkSize();
if(subTrunkSize <= freeSlots + 1) {
// whole trunk is consumed, can use an extra slot since
trunk.setSubNode(subNodeI, std::move(subTrunk.subNodes[0]), subTrunk.getBoundsOfSubNode(0));
trunkSize = TrunkSIMDHelperFallback::transferNodes(subTrunk, 1, subTrunkSize, trunk, trunkSize);
alloc.freeTrunk(&subTrunk);
if(trunkSize >= BRANCH_FACTOR) return trunkSize;
freeSlots = BRANCH_FACTOR - trunkSize;
} else {
// not consuming the whole trunk add what we can
int resultingSubTrunkSize = subTrunkSize - freeSlots;
int resultingSize = TrunkSIMDHelperFallback::transferNodes(subTrunk, resultingSubTrunkSize, subTrunkSize, trunk, trunkSize);
subNode.setTrunkSize(resultingSubTrunkSize);
trunk.setBoundsOfSubNode(subNodeI, TrunkSIMDHelperFallback::getTotalBounds(subTrunk, resultingSubTrunkSize));
assert(resultingSize == BRANCH_FACTOR);
return resultingSize;
}
}
}
return trunkSize;
}
static int improveStructureRecursive(TrunkAllocator& alloc, TreeTrunk& trunk, int trunkSize) {
bool givenTrunkIsLeafTrunk = true;
for(int i = 0; i < trunkSize; i++) {
TreeNodeRef& subNode = trunk.subNodes[i];
if(subNode.isTrunkNode()) {
TreeTrunk& subTrunk = subNode.asTrunk();
int subTrunkSize = subNode.getTrunkSize();
subTrunkSize = improveStructureRecursive(alloc, subTrunk, subTrunkSize);
subNode.setTrunkSize(subTrunkSize);
if(!subNode.isGroupHead()) givenTrunkIsLeafTrunk = false;
}
}
if(givenTrunkIsLeafTrunk) return trunkSize;
trunkSize = moveElementsOutOfGroup(alloc, trunk, trunkSize);
if(trunkSize != BRANCH_FACTOR) return trunkSize;
if(isLeafTrunk(trunk, trunkSize)) return trunkSize;
improveTrunkVertical(trunk); // trunkSize == BRANCH_FACTOR
improveTrunkHorizontal(alloc, trunk); // trunkSize == BRANCH_FACTOR
return trunkSize;
}
void BoundsTreePrototype::improveStructure() {
improveStructureRecursive(this->allocator, this->baseTrunk, this->baseTrunkSize);
}
void BoundsTreePrototype::maxImproveStructure() {
for(int i = 0; i < 5; i++) {
this->improveStructure();
}
}
};
================================================
FILE: Physics3D/boundstree/boundsTree.h
================================================
#pragma once
#include "../math/fix.h"
#include "../math/position.h"
#include "../math/bounds.h"
#include "../datastructures/iteratorEnd.h"
#include "../datastructures/iteratorFactory.h"
#include <cstdint>
#include <utility>
#include <cassert>
#include <limits>
#include <array>
#include <optional>
#include <iostream>
#include <stack>
namespace P3D {
constexpr int BRANCH_FACTOR = 8;
static_assert((BRANCH_FACTOR & (BRANCH_FACTOR - 1)) == 0, "Branch factor must be power of 2");
struct TreeTrunk;
inline float computeCost(const BoundsTemplate<float>& bounds) {
Vec3f d = bounds.getDiagonal();
return d.x + d.y + d.z;
}
inline float computeAdditionCost(const BoundsTemplate<float>& oldBounds, const BoundsTemplate<float>& extraBounds) {
return computeCost(unionOfBounds(oldBounds, extraBounds)) - computeCost(oldBounds);
}
class TreeNodeRef {
friend struct TreeTrunk;
static constexpr std::uintptr_t SIZE_DATA_MASK = BRANCH_FACTOR - 1;
static constexpr std::uintptr_t GROUP_HEAD_MASK = BRANCH_FACTOR;
static constexpr std::uintptr_t PTR_MASK = ~(SIZE_DATA_MASK | GROUP_HEAD_MASK);
static constexpr std::uintptr_t INVALID_REF = 0xADADADADADADADAD;
/* encoding:
0b...pppppgsss
(this is if BRANCH_FACTOR == 8)
Last 3 bits specify type:
0b000: leaf node -> ptr points to object
else : trunk node -> ptr points to TreeTrunk
g bit specifies 'isGroupHead'
s bits specify size of this trunk node - 1. 0b111 is a trunknode of size 8
*/
std::uintptr_t ptr;
inline int getSizeData() const {
return static_cast<int>(ptr & SIZE_DATA_MASK);
}
public:
#ifndef NDEBUG
TreeNodeRef() noexcept : ptr(INVALID_REF) {}
#else
TreeNodeRef() = default;
#endif
inline explicit TreeNodeRef(TreeTrunk* trunk, int trunkSize, bool isGroupHead) noexcept;
inline explicit TreeNodeRef(void* ptr) noexcept : ptr(reinterpret_cast<std::uintptr_t>(ptr)) {
assert((this->ptr & SIZE_DATA_MASK) == 0);
}
TreeNodeRef(const TreeNodeRef&) = delete;
TreeNodeRef& operator=(const TreeNodeRef&) = delete;
#ifndef NDEBUG
TreeNodeRef(TreeNodeRef&& other) noexcept : ptr(other.ptr) { other.ptr = INVALID_REF; }
TreeNodeRef& operator=(TreeNodeRef&& other) noexcept { this->ptr = other.ptr; other.ptr = INVALID_REF; return *this; }
#else
TreeNodeRef(TreeNodeRef&& other) = default;
TreeNodeRef& operator=(TreeNodeRef&& other) = default;
#endif
inline bool isLeafNode() const {
assert(this->ptr != INVALID_REF);
return getSizeData() == 0;
}
inline bool isTrunkNode() const {
assert(this->ptr != INVALID_REF);
return getSizeData() != 0;
}
inline int getTrunkSize() const {
assert(isTrunkNode());
return getSizeData() + 1;
}
inline void setTrunkSize(int newSize) {
assert(isTrunkNode());
assert(newSize >= 2 && newSize <= BRANCH_FACTOR);
this->ptr = (this->ptr & ~SIZE_DATA_MASK) | (newSize - 1);
}
inline void setObject(void* newObject) {
assert(isLeafNode());
this->ptr = reinterpret_cast<std::uintptr_t>(newObject);
assert((this->ptr & SIZE_DATA_MASK) == 0);
}
inline void makeGroupHead() {
assert(isTrunkNode());
this->ptr |= GROUP_HEAD_MASK;
}
inline void removeGroupHead() {
assert(isTrunkNode());
this->ptr &= ~GROUP_HEAD_MASK;
}
inline bool isGroupHead() const {
assert(isTrunkNode());
return (ptr & GROUP_HEAD_MASK) != 0;
}
inline bool isGroupHeadOrLeaf() const {
if(isTrunkNode()) {
return (ptr & GROUP_HEAD_MASK) != 0;
} else {
return true;
}
}
inline const TreeTrunk& asTrunk() const;
inline TreeTrunk& asTrunk();
inline void* asObject() const;
// expects a function of the form BoundsTemplate<float>(const CastTo&)
template<typename CastTo, typename GetObjectBoundsFunc>
inline BoundsTemplate<float> recalculateBoundsRecursive(const GetObjectBoundsFunc& getObjBounds);
};
struct TrunkSIMDHelperFallback;
template<size_t Size>
struct alignas(64) BoundsArray {
float xMin[Size];
float yMin[Size];
float zMin[Size];
float xMax[Size];
float yMax[Size];
float zMax[Size];
inline BoundsTemplate<float> getBounds(int index) const {
assert(index >= 0 && index < Size);
BoundsTemplate<float> result;
result.min.x = xMin[index];
result.min.y = yMin[index];
result.min.z = zMin[index];
result.max.x = xMax[index];
result.max.y = yMax[index];
result.max.z = zMax[index];
return result;
}
inline void setBounds(int index, const BoundsTemplate<float>& newBounds) {
assert(index >= 0 && index < Size);
xMin[index] = newBounds.min.x;
yMin[index] = newBounds.min.y;
zMin[index] = newBounds.min.z;
xMax[index] = newBounds.max.x;
yMax[index] = newBounds.max.y;
zMax[index] = newBounds.max.z;
}
inline void move(int from, int to) {
assert(from >= 0 && from < Size);
assert(to >= 0 && to < Size);
xMin[to] = xMin[from];
yMin[to] = yMin[from];
zMin[to] = zMin[from];
xMax[to] = xMax[from];
yMax[to] = yMax[from];
zMax[to] = zMax[from];
}
};
struct alignas(64) TreeTrunk {
BoundsArray<BRANCH_FACTOR> subNodeBounds;
TreeNodeRef subNodes[BRANCH_FACTOR];
inline BoundsTemplate<float> getBoundsOfSubNode(int subNode) const {
return this->subNodeBounds.getBounds(subNode);
}
inline void setBoundsOfSubNode(int subNode, const BoundsTemplate<float>& newBounds) {
this->subNodeBounds.setBounds(subNode, newBounds);
}
inline void moveSubNode(int from, int to) {
this->subNodeBounds.move(from, to);
this->subNodes[to] = std::move(this->subNodes[from]);
}
inline void setSubNode(int subNode, TreeNodeRef&& newNode, const BoundsTemplate<float>& newBounds) {
this->subNodeBounds.setBounds(subNode, newBounds);
subNodes[subNode] = std::move(newNode);
}
};
TreeNodeRef::TreeNodeRef(TreeTrunk* trunk, int trunkSize, bool isGroupHead) noexcept : ptr(reinterpret_cast<std::uintptr_t>(trunk) | (static_cast<std::uintptr_t>(trunkSize) - 1) | (isGroupHead ? BRANCH_FACTOR : 0)) {
assert(trunkSize >= 2 && trunkSize <= BRANCH_FACTOR); // trunkSize must be between 2-BRANCH_FACTOR
assert((reinterpret_cast<std::uintptr_t>(trunk) & (BRANCH_FACTOR * sizeof(int64_t) - 1)) == 0); // check trunk is aligned correctly
}
const TreeTrunk& TreeNodeRef::asTrunk() const {
assert(this->ptr != INVALID_REF);
assert(isTrunkNode());
return *reinterpret_cast<TreeTrunk*>(ptr & PTR_MASK);
}
TreeTrunk& TreeNodeRef::asTrunk() {
assert(this->ptr != INVALID_REF);
assert(isTrunkNode());
return *reinterpret_cast<TreeTrunk*>(ptr & PTR_MASK);
}
void* TreeNodeRef::asObject() const {
assert(this->ptr != INVALID_REF);
assert(isLeafNode());
return reinterpret_cast<TreeTrunk*>(ptr & ~SIZE_DATA_MASK);
}
struct OverlapMatrix {
bool overlapData[BRANCH_FACTOR*BRANCH_FACTOR]{};
inline bool* operator[](size_t idx) {return overlapData+BRANCH_FACTOR*idx;}
inline const bool* operator[](size_t idx) const {return overlapData+BRANCH_FACTOR*idx;}
};
struct TrunkSIMDHelperFallback {
static BoundsTemplate<float> getTotalBounds(const TreeTrunk& trunk, int upTo);
static BoundsTemplate<float> getTotalBoundsWithout(const TreeTrunk& trunk, int upTo, int without);
// returns a list of bounds, every index contains the total bounds without that subNode
static BoundsArray<BRANCH_FACTOR> getAllTotalBoundsWithout(const TreeTrunk& trunk, int upTo);
static std::array<bool, BRANCH_FACTOR> getAllContainsBounds(const TreeTrunk& trunk, const BoundsTemplate<float>& boundsToContain);
static std::array<float, BRANCH_FACTOR> computeAllCosts(const TreeTrunk& trunk);
static std::array<float, BRANCH_FACTOR> computeAllCombinationCosts(const BoundsArray<BRANCH_FACTOR>& boundsArr, const BoundsTemplate<float>& boundsExtention);
static std::pair<int, int> computeFurthestObjects(const BoundsArray<BRANCH_FACTOR * 2>& boundsArray, int size);
static int getLowestCombinationCost(const TreeTrunk& trunk, const BoundsTemplate<float>& boundsExtention, int nodeSize);
static std::array<bool, BRANCH_FACTOR> computeOverlapsWith(const TreeTrunk& trunk, int trunkSize, const BoundsTemplate<float>& bounds);
// indexed result[a][b]
static OverlapMatrix computeBoundsOverlapMatrix(const TreeTrunk& trunkA, int trunkASize, const TreeTrunk& trunkB, int trunkBSize);
static OverlapMatrix computeBoundsOverlapMatrixAVX(const TreeTrunk& trunkA, int trunkASize, const TreeTrunk& trunkB, int trunkBSize);
static OverlapMatrix computeBoundsOverlapMatrixSSE(const TreeTrunk& trunkA, int trunkASize, const TreeTrunk& trunkB, int trunkBSize);
// indexed result[i][j] with j >= i+1
static OverlapMatrix computeInternalBoundsOverlapMatrix(const TreeTrunk& trunk, int trunkSize);
static std::array<float, BRANCH_FACTOR> computeAllExtentionCosts(const TreeTrunk& trunk, int trunkSize, const BoundsTemplate<float>& extraBounds);
// returns resulting destTrunk size
static int transferNodes(TreeTrunk& srcTrunk, int srcTrunkStart, int srcTrunkEnd, TreeTrunk& destTrunk, int destTrunkSize);
static BoundsArray<BRANCH_FACTOR * 2> combineBoundsArrays(const TreeTrunk& trunkA, int trunkASize, const TreeTrunk& trunkB, int trunkBSize);
// returns true if modified
static bool exchangeNodesBetween(TreeTrunk& trunkA, int& trunkASize, TreeTrunk& trunkB, int& trunkBSize);
};
template<typename CastTo, typename GetObjectBoundsFunc>
inline BoundsTemplate<float> TreeNodeRef::recalculateBoundsRecursive(const GetObjectBoundsFunc& getObjBounds) {
int sizeData = getSizeData();
if(sizeData == 0) { // is leaf node
return getObjBounds(*reinterpret_cast<const CastTo*>(this->asObject()));
} else {
int trunkSize = sizeData + 1;
TreeTrunk* trunk = this->asTrunk();
for(int i = 0; i < trunkSize; i++) {
trunk->setBoundsOfSubNode(i, trunk->subNodes[i].recalculateBoundsRecursive(getObjBounds));
}
return TrunkSIMDHelperFallback::getTotalBounds(*trunk, trunkSize);
}
}
class TrunkAllocator {
size_t allocationCount;
public:
TrunkAllocator();
~TrunkAllocator();
TrunkAllocator(const TrunkAllocator&) = delete;
TrunkAllocator& operator=(const TrunkAllocator&) = delete;
TrunkAllocator(TrunkAllocator&& other) noexcept;
TrunkAllocator& operator=(TrunkAllocator&& other) noexcept;
TreeTrunk* allocTrunk();
void freeTrunk(TreeTrunk* trunk);
void freeAllTrunks(TreeTrunk& baseTrunk, int baseTrunkSize);
};
int addRecursive(TrunkAllocator& allocator, TreeTrunk& curTrunk, int curTrunkSize, TreeNodeRef&& newNode, const BoundsTemplate<float>& bounds);
int removeRecursive(TrunkAllocator& allocator, TreeTrunk& curTrunk, int curTrunkSize, const void* objectToRemove, const BoundsTemplate<float>& bounds);
bool containsObjectRecursive(const TreeTrunk& trunk, int trunkSize, const void* object, const BoundsTemplate<float>& bounds);
const TreeNodeRef* getGroupRecursive(const TreeTrunk& curTrunk, int curTrunkSize, const void* groupRepresentative, const BoundsTemplate<float>& representativeBounds);
/*
Expects a function of the form BoundsTemplate<float>(TreeNodeRef& groupNode, const BoundsTemplate<float>& groupNodeBounds)
Should return the new bounds of the node.
The input group and resulting group should be in the normal form of a group:
if Trunk node => isGroupHead is enabled, no trunk node below has isGroupHead
or Leaf node
*/
template<typename Func>
inline bool modifyGroupRecursive(TrunkAllocator& allocator, TreeTrunk& curTrunk, int curTrunkSize, const void* groupRepresentative, const BoundsTemplate<float>& groupRepresentativeBounds, const Func& modification) {
assert(curTrunkSize >= 0 && curTrunkSize <= BRANCH_FACTOR);
std::array<bool, BRANCH_FACTOR> couldContain = TrunkSIMDHelperFallback::getAllContainsBounds(curTrunk, groupRepresentativeBounds);
for(int i = 0; i < curTrunkSize; i++) {
if(!couldContain[i]) continue;
TreeNodeRef& subNode = curTrunk.subNodes[i];
if(subNode.isTrunkNode()) {
TreeTrunk& subTrunk = subNode.asTrunk();
int subTrunkSize = subNode.getTrunkSize();
if(subNode.isGroupHead()) {
if(containsObjectRecursive(subTrunk, subTrunkSize, groupRepresentative, groupRepresentativeBounds)) {
BoundsTemplate<float> newTrunkBounds = modification(subNode, curTrunk.getBoundsOfSubNode(i));
assert(subNode.isGroupHeadOrLeaf());
curTrunk.setBoundsOfSubNode(i, newTrunkBounds);
return true;
}
} else {
if(modifyGroupRecursive(allocator, subTrunk, subTrunkSize, groupRepresentative, groupRepresentativeBounds, modification)) {
curTrunk.setBoundsOfSubNode(i, TrunkSIMDHelperFallback::getTotalBounds(subTrunk, subTrunkSize));
return true;
}
}
} else {
if(subNode.asObject() == groupRepresentative) {
BoundsTemplate<float> newTrunkBounds = modification(subNode, curTrunk.getBoundsOfSubNode(i));
assert(subNode.isGroupHeadOrLeaf());
curTrunk.setBoundsOfSubNode(i, newTrunkBounds);
return true;
}
}
}
return false;
}
/*
Expects a function of the form std::optional<BoundsTemplate<float>>(TreeNodeRef& groupNode, const BoundsTemplate<float>& groupNodeBounds)
Should return the new bounds of the node.
The input group and resulting group should be in the normal form of a group:
if Trunk node => isGroupHead is enabled, no trunk node below has isGroupHead
or Leaf node
*/
template<typename Func>
inline int contractGroupRecursive(TrunkAllocator& allocator, TreeTrunk& curTrunk, int curTrunkSize, const void* groupRepresentative, const BoundsTemplate<float>& groupRepresentativeBounds, const Func& modification) {
assert(curTrunkSize >= 0 && curTrunkSize <= BRANCH_FACTOR);
std::array<bool, BRANCH_FACTOR> couldContain = TrunkSIMDHelperFallback::getAllContainsBounds(curTrunk, groupRepresentativeBounds);
for(int i = 0; i < curTrunkSize; i++) {
if(!couldContain[i]) continue;
TreeNodeRef& subNode = curTrunk.subNodes[i];
if(subNode.isTrunkNode()) {
TreeTrunk& subTrunk = subNode.asTrunk();
int subTrunkSize = subNode.getTrunkSize();
if(subNode.isGroupHead()) {
if(containsObjectRecursive(subTrunk, subTrunkSize, groupRepresentative, groupRepresentativeBounds)) {
std::optional<BoundsTemplate<float>> newTrunkBounds = modification(subNode, curTrunk.getBoundsOfSubNode(i));
if(newTrunkBounds.has_value()) {
assert(subNode.isGroupHeadOrLeaf());
curTrunk.setBoundsOfSubNode(i, newTrunkBounds.value());
return curTrunkSize;
} else {
curTrunk.moveSubNode(curTrunkSize - 1, i);
return curTrunkSize - 1;
}
}
} else {
int newSubSize = contractGroupRecursive(allocator, subTrunk, subTrunkSize, groupRepresentative, groupRepresentativeBounds, modification);
if(newSubSize != -1) {
assert(newSubSize >= 1);
if(newSubSize == 1) {
curTrunk.setSubNode(i, std::move(subTrunk.subNodes[0]), subTrunk.getBoundsOfSubNode(0));
allocator.freeTrunk(&subTrunk);
} else {
subNode.setTrunkSize(newSubSize);
curTrunk.setBoundsOfSubNode(i, TrunkSIMDHelperFallback::getTotalBounds(subTrunk, newSubSize));
}
return curTrunkSize;
}
}
} else {
if(subNode.asObject() == groupRepresentative) {
std::optional<BoundsTemplate<float>> newTrunkBounds = modification(subNode, curTrunk.getBoundsOfSubNode(i));
if(newTrunkBounds.has_value()) {
assert(subNode.isGroupHeadOrLeaf());
curTrunk.setBoundsOfSubNode(i, newTrunkBounds.value());
return curTrunkSize;
} else {
curTrunk.moveSubNode(curTrunkSize - 1, i);
return curTrunkSize - 1;
}
}
}
}
return -1;
}
// expects a function of the form void(Boundable& object)
template<typename Boundable, typename Func>
inline void forEachRecurse(const TreeTrunk& curTrunk, int curTrunkSize, const Func& func) {
for(int i = 0; i < curTrunkSize; i++) {
const TreeNodeRef& subNode = curTrunk.subNodes[i];
if(subNode.isTrunkNode()) {
forEachRecurse<Boundable, Func>(subNode.asTrunk(), subNode.getTrunkSize(), func);
} else {
func(*static_cast<Boundable*>(subNode.asObject()));
}
}
}
// expects a filter of the form std::array<bool, BRANCH_FACTOR>(const TreeTrunk& trunk, int trunkSize)
// expects a function of the form void(Boundable& object)
template<typename Boundable, typename Filter, typename Func>
inline void forEachFilteredRecurse(const TreeTrunk& curTrunk, int curTrunkSize, const Filter& filter, const Func& func) {
std::array<bool, BRANCH_FACTOR> passes = filter(curTrunk, curTrunkSize);
for(int i = 0; i < curTrunkSize; i++) {
if(passes[i]) {
const TreeNodeRef& subNode = curTrunk.subNodes[i];
if(subNode.isTrunkNode()) {
forEachFilteredRecurse<Boundable, Filter, Func>(subNode.asTrunk(), subNode.getTrunkSize(), filter, func);
} else {
func(*static_cast<Boundable*>(subNode.asObject()));
}
}
}
}
// expects a function of the form void(Boundable*, Boundable*)
// Calls the given function for each pair of leaf nodes from the two trunks
template<typename Boundable, typename SIMDHelper, typename Func>
void forEachColissionWithRecursive(Boundable* obj, const BoundsTemplate<float>& objBounds, const TreeTrunk& trunk, int trunkSize, const Func& func) {
std::array<bool, BRANCH_FACTOR> collidesWith = SIMDHelper::computeOverlapsWith(trunk, trunkSize, objBounds);
for(int i = 0; i < trunkSize; i++) {
if(!collidesWith[i]) continue;
const TreeNodeRef& subNode = trunk.subNodes[i];
if(subNode.isTrunkNode()) {
forEachColissionWithRecursive<Boundable, SIMDHelper, Func>(obj, objBounds, subNode.asTrunk(), subNode.getTrunkSize(), func);
} else {
func(obj, static_cast<Boundable*>(subNode.asObject()));
}
}
}
// expects a function of the form void(Boundable*, Boundable*)
// Calls the given function for each pair of leaf nodes from the two trunks
template<typename Boundable, typename SIMDHelper, typename Func>
void forEachColissionWithRecursive(const TreeTrunk& trunk, int trunkSize, Boundable* obj, const BoundsTemplate<float>& objBounds, const Func& func) {
std::array<bool, BRANCH_FACTOR> collidesWith = SIMDHelper::computeOverlapsWith(trunk, trunkSize, objBounds);
for(int i = 0; i < trunkSize; i++) {
if(!collidesWith[i]) continue;
const TreeNodeRef& subNode = trunk.subNodes[i];
if(subNode.isTrunkNode()) {
forEachColissionWithRecursive<Boundable, SIMDHelper, Func>(subNode.asTrunk(), subNode.getTrunkSize(), obj, objBounds, func);
} else {
func(static_cast<Boundable*>(subNode.asObject()), obj);
}
}
}
// expects a function of the form void(Boundable*, Boundable*)
// Calls the given function for each pair of leaf nodes from the two trunks
template<typename Boundable, typename SIMDHelper, typename Func>
void forEachColissionBetweenRecursive(const TreeTrunk& trunkA, int trunkASize, const TreeTrunk& trunkB, int trunkBSize, const Func& func) {
OverlapMatrix overlapBetween = SIMDHelper::computeBoundsOverlapMatrix(trunkA, trunkASize, trunkB, trunkBSize);
for(int a = 0; a < trunkASize; a++) {
const TreeNodeRef& aNode = trunkA.subNodes[a];
bool aIsTrunk = aNode.isTrunkNode();
for(int b = 0; b < trunkBSize; b++) {
if(!overlapBetween[a][b]) continue;
const TreeNodeRef& bNode = trunkB.subNodes[b];
bool bIsTrunk = bNode.isTrunkNode();
if(aIsTrunk) {
if(bIsTrunk) {
// both trunk nodes
// split both
forEachColissionBetweenRecursive<Boundable, SIMDHelper, Func>(aNode.asTrunk(), aNode.getTrunkSize(), bNode.asTrunk(), bNode.getTrunkSize(), func);
} else {
// a is trunk, b is not
// split a
forEachColissionWithRecursive<Boundable, SIMDHelper, Func>(aNode.asTrunk(), aNode.getTrunkSize(), static_cast<Boundable*>(bNode.asObject()), trunkB.getBoundsOfSubNode(b), func);
}
} else {
if(bIsTrunk) {
// b is trunk, a is not
// split b
forEachColissionWithRecursive<Boundable, SIMDHelper, Func>(static_cast<Boundable*>(aNode.asObject()), trunkA.getBoundsOfSubNode(a), bNode.asTrunk(), bNode.getTrunkSize(), func);
} else {
// both leaf nodes
func(static_cast<Boundable*>(aNode.asObject()), static_cast<Boundable*>(bNode.asObject()));
}
}
}
}
}
// expects a function of the form void(Boundable*, Boundable*)
// Calls the given function for each pair of leaf nodes that are not in the same group and have overlapping bounds
template<typename Boundable, typename SIMDHelper, typename Func>
void forEachColissionInternalRecursive(const TreeTrunk& curTrunk, int curTrunkSize, const Func& func) {
OverlapMatrix internalOverlap = SIMDHelper::computeInternalBoundsOverlapMatrix(curTrunk, curTrunkSize);
for(int a = 0; a < curTrunkSize; a++) {
const TreeNodeRef& aNode = curTrunk.subNodes[a];
bool aIsTrunk = aNode.isTrunkNode();
for(int b = a+1; b < curTrunkSize; b++) {
if(!internalOverlap[a][b]) continue;
const TreeNodeRef& bNode = curTrunk.subNodes[b];
bool bIsTrunk = bNode.isTrunkNode();
if(aIsTrunk) {
if(bIsTrunk) {
// both trunk nodes
// split both
forEachColissionBetweenRecursive<Boundable, SIMDHelper, Func>(aNode.asTrunk(), aNode.getTrunkSize(), bNode.asTrunk(), bNode.getTrunkSize(), func);
} else {
// a is trunk, b is not
// split a
forEachColissionWithRecursive<Boundable, SIMDHelper, Func>(aNode.asTrunk(), aNode.getTrunkSize(), static_cast<Boundable*>(bNode.asObject()), curTrunk.getBoundsOfSubNode(b), func);
}
} else {
if(bIsTrunk) {
// b is trunk, a is not
// split b
forEachColissionWithRecursive<Boundable, SIMDHelper, Func>(static_cast<Boundable*>(aNode.asObject()), curTrunk.getBoundsOfSubNode(a), bNode.asTrunk(), bNode.getTrunkSize(), func);
} else {
// both leaf nodes
func(static_cast<Boundable*>(aNode.asObject()), static_cast<Boundable*>(bNode.asObject()));
}
}
}
}
for(int i = 0; i < curTrunkSize; i++) {
const TreeNodeRef& subNode = curTrunk.subNodes[i];
if(subNode.isTrunkNode() && !subNode.isGroupHead()) {
forEachColissionInternalRecursive<Boundable, SIMDHelper, Func>(subNode.asTrunk(), subNode.getTrunkSize(), func);
}
}
}
class BoundsTreeIteratorPrototype {
struct StackElement {
const TreeTrunk* trunk;
int trunkSize;
int curIndex;
};
std::stack<StackElement> trunkStack;
public:
BoundsTreeIteratorPrototype() = default;
BoundsTreeIteratorPrototype(const TreeTrunk& baseTrunk, int baseTrunkSize) : trunkStack() {
if(baseTrunkSize == 0) return;
trunkStack.push(StackElement{&baseTrunk, baseTrunkSize, 0});
while(trunkStack.top().trunk->subNodes[0].isTrunkNode()) {
const TreeNodeRef& nextNode = trunkStack.top().trunk->subNodes[0];
trunkStack.push(StackElement{&nextNode.asTrunk(), nextNode.getTrunkSize(), 0});
}
}
void* operator*() const {
const StackElement& top = trunkStack.top();
return top.trunk->subNodes[top.curIndex].asObject();
}
BoundsTreeIteratorPrototype& operator++() {
StackElement& top = trunkStack.top();
top.curIndex++;
if(top.curIndex < top.trunkSize) {
const TreeNodeRef& nextNode = trunkStack.top().trunk->subNodes[top.curIndex];
if(nextNode.isTrunkNode()) {
// rise until hitting non trunk node
trunkStack.push(StackElement{&nextNode.asTrunk(), nextNode.getTrunkSize(), 0});
while(trunkStack.top().trunk->subNodes[0].isTrunkNode()) {
const TreeNodeRef& nextNode = trunkStack.top().trunk->subNodes[0];
trunkStack.push(StackElement{&nextNode.asTrunk(), nextNode.getTrunkSize(), 0});
}
}
} else {
// drop down until next available
do {
trunkStack.pop();
if(trunkStack.size() == 0) break; // iteration done
StackElement& top = trunkStack.top();
top.curIndex++;
assert(top.curIndex <= top.trunkSize);
} while(top.curIndex == top.trunkSize); // keep popping
}
return *this;
}
bool operator!=(IteratorEnd) const {
return trunkStack.size() != 0;
}
};
template<typename Filter>
class FilteredTreeIteratorPrototype {
struct StackElement {
const TreeTrunk* trunk;
int trunkSize;
int curIndex;
std::array<bool, BRANCH_FACTOR> filterResults;
};
Filter filter;
std::stack<StackElement> trunkStack;
public:
FilteredTreeIteratorPrototype() = default;
void delveDown() {
while(true) {
again:
StackElement& top = trunkStack.top();
for(; top.curIndex < top.trunkSize; top.curIndex++) {
if(top.filterResults[top.curIndex]) {
const TreeNodeRef& subNode = top.trunk->subNodes[top.curIndex];
if(!subNode.isTrunkNode()) break;
StackElement newElem{&subNode.asTrunk(), subNode.getTrunkSize(), 0};
newElem.filterResults = this->filter(*newElem.trunk, newElem.trunkSize);
trunkStack.push(newElem);
goto again;
}
}
// no available node found, go back up a level
trunkStack.pop();
if(trunkStack.empty()) return; // end of iteration
StackElement& newTop = trunkStack.top();
newTop.curIndex++;
}
}
FilteredTreeIteratorPrototype(const TreeTrunk& baseTrunk, int baseTrunkSize, const Filter& filter) : trunkStack(), filter(filter) {
if(baseTrunkSize == 0) return;
StackElement newElement{&baseTrunk, baseTrunkSize};
newElement.filterResults = this->filter(baseTrunk, baseTrunkSize);
for(int i = 0; i < baseTrunkSize; i++){
if(newElement.filterResults[i]) {
newElement.curIndex = i;
trunkStack.push(newElement);
goto found;
}
}
return; // none of the nodes are suitable
found:;
this->delveDown();
}
void* operator*() const {
const StackElement& top = trunkStack.top();
return top.trunk->subNodes[top.curIndex].asObject();
}
FilteredTreeIteratorPrototype& operator++() {
StackElement& top = trunkStack.top();
top.curIndex++;
this->delveDown();
return *this;
}
bool operator!=(IteratorEnd) const {
return trunkStack.size() != 0;
}
};
class BoundsTreePrototype {
TreeTrunk baseTrunk;
int baseTrunkSize;
TrunkAllocator allocator;
template<typename Boundable>
friend class BoundsTree;
public:
BoundsTreePrototype();
~BoundsTreePrototype();
inline BoundsTreePrototype(BoundsTreePrototype&& other) noexcept : baseTrunk(std::move(other.baseTrunk)), baseTrunkSize(other.baseTrunkSize), allocator(std::move(other.allocator)) {
other.baseTrunkSize = 0;
}
inline BoundsTreePrototype& operator=(BoundsTreePrototype&& other) noexcept {
this->baseTrunk = std::move(other.baseTrunk);
this->baseTrunkSize = other.baseTrunkSize;
this->allocator = std::move(other.allocator);
other.baseTrunkSize = 0;
return *this;
}
void add(void* newObject, const BoundsTemplate<float>& bounds);
void remove(const void* objectToRemove, const BoundsTemplate<float>& bounds);
void addToGroup(void* newObject, const BoundsTemplate<float>& newObjectBounds, const void* groupRepresentative, const BoundsTemplate<float>& groupRepBounds);
void mergeGroups(const void* groupRepA, const BoundsTemplate<float>& repABounds, const void* groupRepB, const BoundsTemplate<float>& repBBounds);
void transferGroupTo(const void* groupRep, const BoundsTemplate<float>& groupRepBounds, BoundsTreePrototype& destinationTree);
void updateObjectBounds(const void* object, const BoundsTemplate<float>& originalBounds, const BoundsTemplate<float>& newBounds);
// oldObject and newObject should have the same bounds
void findAndReplaceObject(const void* oldObject, void* newObject, const BoundsTemplate<float>& bounds);
void disbandGroup(const void* groupRep, const BoundsTemplate<float>& groupRepBounds);
bool contains(const void* object, const BoundsTemplate<float>& bounds) const;
bool groupContains(const void* groupRep, const BoundsTemplate<float>& groupRepBounds, const void* object, const BoundsTemplate<float>& bounds) const;
size_t size() const;
size_t groupSize(const void* groupRep, const BoundsTemplate<float>& groupRepBounds) const;
inline bool isEmpty() const {
return this->baseTrunkSize == 0;
}
void clear();
template<typename GroupIter, typename GroupIterEnd>
void removeSubGroup(GroupIter iter, const GroupIterEnd& iterEnd) {
if(!(iter != iterEnd)) return;
std::pair<const void*, BoundsTemplate<float>> firstObject = *iter;
++iter;
if(!(iter != iterEnd)) { // just one item
this->remove(firstObject.first, firstObject.second);
} else {
int newMainSize = contractGroupRecursive(this->allocator, this->baseTrunk, this->baseTrunkSize, firstObject.first, firstObject.second, [this, &iter, &iterEnd, &firstObject](TreeNodeRef& group, const BoundsTemplate<float>& groupNodeBounds) {
if(!group.isTrunkNode()) {
throw "Attempting to remove more than one object from a single-object group!";
}
TreeTrunk& groupTrunk = group.asTrunk();
int groupTrunkSize = group.getTrunkSize();
groupTrunkSize = removeRecursive(this->allocator, groupTrunk, groupTrunkSize, firstObject.first, firstObject.second);
assert(groupTrunkSize != -1); // should have been verified
do {
std::pair<const void*, BoundsTemplate<float>> currentlyMoving = *iter;
groupTrunkSize = removeRecursive(this->allocator, groupTrunk, groupTrunkSize, currentlyMoving.first, currentlyMoving.second);
if(groupTrunkSize == -1) {
throw "Iterator provided an object which could not be found in this group!";
}
++iter;
} while(iter != iterEnd);
if(groupTrunkSize >= 2) {
group.setTrunkSize(groupTrunkSize);
return std::optional<BoundsTemplate<float>>(TrunkSIMDHelperFallback::getTotalBounds(groupTrunk, groupTrunkSize));
} else if(groupTrunkSize == 1) {
BoundsTemplate<float> resultingBounds = groupTrunk.getBoundsOfSubNode(0);
group = std::move(groupTrunk.subNodes[0]);
if(group.isTrunkNode()) {
group.makeGroupHead(); // make sure to preserve the group head if the trunk is overwritten
}
this->allocator.freeTrunk(&groupTrunk);
return std::optional<BoundsTemplate<float>>(resultingBounds);
} else {
this->allocator.freeTrunk(&groupTrunk);
return std::optional<BoundsTemplate<float>>();
}
});
this->baseTrunkSize = newMainSize;
}
}
// the given iterator should return objects of type std::pair<void*, BoundsTemplate<float>>
template<typename GroupIter, typename GroupIterEnd>
void transferSplitGroupTo(GroupIter iter, const GroupIterEnd& iterEnd, BoundsTreePrototype& destinationTree) {
if(!(iter != iterEnd)) return; // no items
this->removeSubGroup(iter, iterEnd);
std::pair<const void*, BoundsTemplate<float>> firstObject = *iter;
++iter;
if(iter != iterEnd) {
TreeTrunk* newGroupTrunk = destinationTree.allocator.allocTrunk();
newGroupTrunk->setSubNode(0, TreeNodeRef(const_cast<void*>(firstObject.first)), firstObject.second);
int newGroupTrunkSize = 1;
do {
std::pair<const void*, BoundsTemplate<float>> obj = *iter;
newGroupTrunkSize = addRecursive(destinationTree.allocator, *newGroupTrunk, newGroupTrunkSize, TreeNodeRef(const_cast<void*>(obj.first)), obj.second);
++iter;
} while(iter != iterEnd);
destinationTree.baseTrunkSize = addRecursive(destinationTree.allocator, destinationTree.baseTrunk, destinationTree.baseTrunkSize, TreeNodeRef(newGroupTrunk, newGroupTrunkSize, true), TrunkSIMDHelperFallback::getTotalBounds(*newGroupTrunk, newGroupTrunkSize));
} else {
destinationTree.add(const_cast<void*>(firstObject.first), firstObject.second);
}
}
// the given iterator should return objects of type std::pair<void*, BoundsTemplate<float>>
template<typename GroupIter, typename GroupIterEnd>
void splitGroup(GroupIter iter, const GroupIterEnd& iterEnd) {
this->transferSplitGroupTo(iter, iterEnd, *this);
}
void improveStructure();
void maxImproveStructure();
BoundsTreeIteratorPrototype begin() const { return BoundsTreeIteratorPrototype(baseTrunk, baseTrunkSize); }
IteratorEnd end() const { return IteratorEnd(); }
template<typename Filter>
IteratorFactoryWithEnd<FilteredTreeIteratorPrototype<Filter>> iterFiltered(const Filter& filter) const {
return IteratorFactoryWithEnd<FilteredTreeIteratorPrototype<Filter>>{FilteredTreeIteratorPrototype<Filter>(baseTrunk, baseTrunkSize, filter)};
}
// unsafe functions
inline std::pair<TreeTrunk&, int> getBaseTrunk() { return std::pair<TreeTrunk&, int>(this->baseTrunk, this->baseTrunkSize); }
inline std::pair<const TreeTrunk&, int> getBaseTrunk() const { return std::pair<const TreeTrunk&, int>(this->baseTrunk, this->baseTrunkSize); }
inline TrunkAllocator& getAllocator() { return allocator; }
inline const TrunkAllocator& getAllocator() const { return allocator; }
void addGroupTrunk(TreeTrunk* newNode, int newNodeSize);
};
template<typename Boundable>
void recalculateBoundsRecursive(TreeTrunk& curTrunk, int curTrunkSize) {
for(int i = 0; i < curTrunkSize; i++) {
TreeNodeRef& subNode = curTrunk.subNodes[i];
if(subNode.isTrunkNode()) {
TreeTrunk& subTrunk = subNode.asTrunk();
int subTrunkSize = subNode.getTrunkSize();
recalculateBoundsRecursive<Boundable>(subTrunk, subTrunkSize);
curTrunk.setBoundsOfSubNode(i, TrunkSIMDHelperFallback::getTotalBounds(subTrunk, subTrunkSize));
} else {
Boundable* object = static_cast<Boundable*>(subNode.asObject());
curTrunk.setBoundsOfSubNode(i, object->getBounds());
}
}
}
template<typename Boundable>
bool updateGroupBoundsRecursive(TreeTrunk& curTrunk, int curTrunkSize, const Boundable* groupRep, const BoundsTemplate<float>& originalGroupRepBounds) {
assert(curTrunkSize >= 0 && curTrunkSize <= BRANCH_FACTOR);
std::array<bool, BRANCH_FACTOR> couldContain = TrunkSIMDHelperFallback::getAllContainsBounds(curTrunk, originalGroupRepBounds);
for(int i = 0; i < curTrunkSize; i++) {
if(!couldContain[i]) continue;
TreeNodeRef& subNode = curTrunk.subNodes[i];
if(subNode.isTrunkNode()) {
TreeTrunk& subTrunk = subNode.asTrunk();
int subTrunkSize = subNode.getTrunkSize();
if(subNode.isGroupHead()) {
if(containsObjectRecursive(subTrunk, subTrunkSize, groupRep, originalGroupRepBounds)) {
recalculateBoundsRecursive<Boundable>(subTrunk, subTrunkSize);
curTrunk.setBoundsOfSubNode(i, TrunkSIMDHelperFallback::getTotalBounds(subTrunk, subTrunkSize));
return true;
}
} else {
if(updateGroupBoundsRecursive<Boundable>(subTrunk, subTrunkSize, groupRep, originalGroupRepBounds)) {
curTrunk.setBoundsOfSubNode(i, TrunkSIMDHelperFallback::getTotalBounds(subTrunk, subTrunkSize));
return true;
}
}
} else {
if(subNode.asObject() == groupRep) {
curTrunk.setBoundsOfSubNode(i, groupRep->getBounds());
return true;
}
}
}
return false;
}
template<typename Boundable, typename UnderlyingIter>
class BoundableCastIterator {
UnderlyingIter iter;
public:
BoundableCastIterator() = default;
BoundableCastIterator(const UnderlyingIter& iter) : iter(iter) {}
BoundableCastIterator(const TreeTrunk& baseTrunk, int baseTrunkSize) : iter(baseTrunk, baseTrunkSize) {}
BoundableCastIterator& operator++() { ++iter; return *this; }
Boundable& operator*() const { return *static_cast<Boundable*>(*iter); }
bool operator!=(IteratorEnd) const { return iter != IteratorEnd{}; }
};
template<typename Boundable>
class BoundsTree {
BoundsTreePrototype tree;
public:
inline const BoundsTreePrototype& getPrototype() const { return tree; }
inline BoundsTreePrototype& getPrototype() { return tree; }
template<typename BoundableIter>
struct BoundableIteratorAdapter {
BoundableIter iter;
std::pair<const void*, BoundsTemplate<float>> operator*() const {
const Boundable* item = *iter;
return std::pair<const void*, BoundsTemplate<float>>(static_cast<const void*>(item), item->getBounds());
}
BoundableIteratorAdapter& operator++() {
++iter;
return *this;
}
template<typename BoundableIterEnd>
bool operator!=(const BoundableIterEnd& end) const {
return this->iter != end;
}
};
void add(Boundable* newObject) {
tree.add(static_cast<void*>(newObject), newObject->getBounds());
}
void remove(const Boundable* objectToRemove) {
tree.remove(static_cast<const void*>(objectToRemove), objectToRemove->getBounds());
}
void addToGroup(Boundable* newObject, const Boundable* groupRepresentative) {
tree.addToGroup(static_cast<void*>(newObject), newObject->getBounds(), static_cast<const void*>(groupRepresentative), groupRepresentative->getBounds());
}
template<typename BoundableIter, typename BoundableIterEnd>
void addAllToGroup(BoundableIter iter, const BoundableIterEnd& iterEnd, const Boundable* groupRep) {
if(!(iter != iterEnd)) return;
modifyGroupRecursive(tree.allocator, tree.baseTrunk, tree.baseTrunkSize, groupRep, groupRep->getBounds(), [this, &iter, &iterEnd](TreeNodeRef& groupNode, BoundsTemplate<float> groupBounds) {
if(groupNode.isLeafNode()) {
TreeTrunk* newTrunk = this->tree.allocator.allocTrunk();
newTrunk->setSubNode(0, std::move(groupNode), groupBounds);
Boundable* newObj = *iter;
BoundsTemplate<float> newObjBounds = newObj->getBounds();
newTrunk->setSubNode(1, TreeNodeRef(newObj), newObjBounds);
groupNode = TreeNodeRef(newTrunk, 2, true);
++iter;
}
TreeTrunk& trunk = groupNode.asTrunk();
int curTrunkSize = groupNode.getTrunkSize();
while(iter != iterEnd) {
Boundable* curObj = *iter;
BoundsTemplate<float> curObjBounds = curObj->getBounds();
curTrunkSize = addRecursive(this->tree.allocator, trunk, curTrunkSize, TreeNodeRef(curObj), curObjBounds);
++iter;
}
return TrunkSIMDHelperFallback::getTotalBounds(trunk, curTrunkSize);
});
}
void mergeGroups(const Boundable* groupRepA, const Boundable* groupRepB) {
tree.mergeGroups(static_cast<const void*>(groupRepA), groupRepA->getBounds(), static_cast<const void*>(groupRepB), groupRepB->getBounds());
}
bool contains(const Boundable* object) const {
return tree.contains(static_cast<const void*>(object), object->getBounds());
}
bool groupContains(const Boundable* groupRep, const Boundable* object) const {
assert(this->contains(groupRep));
return tree.groupContains(static_cast<const void*>(groupRep), groupRep->getBounds(), static_cast<const void*>(object), object->getBounds());
}
void updateObjectBounds(const Boundable* object, const BoundsTemplate<float>& originalBounds) {
tree.updateObjectBounds(static_cast<const void*>(object), originalBounds, object->getBounds());
}
void updateObjectGroupBounds(const Boundable* groupRep, const BoundsTemplate<float>& originalGroupRepBounds) {
bool success = updateGroupBoundsRecursive<Boundable>(tree.baseTrunk, tree.baseTrunkSize, groupRep, originalGroupRepBounds);
if(!success) throw "groupRep was not found in tree!";
}
// oldObject and newObject should have the same bounds
void findAndReplaceObject(const Boundable* oldObject, Boundable* newObject, const BoundsTemplate<float>& bounds) {
assert(this->tree.contains(oldObject, bounds));
tree.findAndReplaceObject(static_cast<const void*>(oldObject), static_cast<void*>(newObject), bounds);
}
void disbandGroup(const Boundable* groupRep) {
assert(this->contains(groupRep));
tree.disbandGroup(static_cast<const void*>(groupRep), groupRep->getBounds());
}
size_t size() const {
return tree.size();
}
size_t groupSize(const Boundable* groupRep) const {
return tree.groupSize(static_cast<const void*>(groupRep), groupRep->getBounds());
}
bool isEmpty() const {
return tree.isEmpty();
}
void clear() {
tree.clear();
}
void transferGroupTo(const Boundable* groupRep, BoundsTree& destinationTree) {
tree.transferGroupTo(static_cast<const void*>(groupRep), groupRep->getBounds(), destinationTree.tree);
}
// the given iterator should return objects of type Boundable*
template<typename GroupIter, typename GroupIterEnd>
void transferSplitGroupTo(GroupIter&& iter, const GroupIterEnd& iterEnd, BoundsTree& destinationTree) {
tree.transferSplitGroupTo(BoundableIteratorAdapter<GroupIter>{std::move(iter)}, iterEnd, destinationTree.tree);
}
void transferTo(Boundable* obj, BoundsTree& destinationTree) {
BoundsTemplate<float> bounds = obj->getBounds();
tree.remove(static_cast<void*>(obj), bounds);
destinationTree.tree.add(static_cast<void*>(obj), bounds);
}
void moveOutOfGroup(Boundable* obj) {
BoundsTemplate<float> bounds = obj->getBounds();
tree.remove(static_cast<void*>(obj), bounds);
tree.add(static_cast<void*>(obj), bounds);
}
// the given iterator should return objects of type Boundable*
template<typename GroupIter, typename GroupIterEnd>
void splitGroup(GroupIter iter, const GroupIterEnd& iterEnd) {
tree.splitGroup(BoundableIteratorAdapter<GroupIter>{std::move(iter)}, iterEnd);
}
// expects a function of the form void(Boundable& object)
template<typename Func>
void forEach(const Func& func) const {
forEachRecurse<Boundable, Func>(this->tree.baseTrunk, this->tree.baseTrunkSize, func);
}
// expects a function of the form void(Boundable& object)
template<typename Filter, typename Func>
void forEachFiltered(const Filter& filter, const Func& func) const {
forEachFilteredRecurse<Boundable, Filter, Func>(this->tree.baseTrunk, this->tree.baseTrunkSize, filter, func);
}
// expects a function of the form void(Boundable& object)
template<typename Func>
void forEachInGroup(const void* groupRepresentative, const BoundsTemplate<float>& groupRepBounds, const Func& func) const {
const TreeNodeRef* group = getGroupRecursive(this->tree.baseTrunk, this->tree.baseTrunkSize, groupRepresentative, groupRepBounds);
if(group == nullptr) {
throw "Group not found!";
}
if(group->isTrunkNode()) {
forEachRecurse<Boundable, Func>(group->asTrunk(), group->getTrunkSize(), func);
} else {
func(*static_cast<Boundable*>(group->asObject()));
}
}
BoundableCastIterator<Boundable, BoundsTreeIteratorPrototype> begin() const { return BoundableCastIterator<Boundable, BoundsTreeIteratorPrototype>(this->tree.begin()); }
IteratorEnd end() const { return IteratorEnd(); }
template<typename Filter>
IteratorFactoryWithEnd<BoundableCastIterator<Boundable, FilteredTreeIteratorPrototype<Filter>>> iterFiltered(const Filter& filter) const {
return IteratorFactoryWithEnd<BoundableCastIterator<Boundable, FilteredTreeIteratorPrototype<Filter>>>{
BoundableCastIterator<Boundable, FilteredTreeIteratorPrototype<Filter>>(
FilteredTreeIteratorPrototype<Filter>(this->tree.baseTrunk, this->tree.baseTrunkSize, filter)
)
};
}
template<typename Func>
void forEachColission(const Func& func) const {
if(this->tree.baseTrunkSize == 0) return;
forEachColissionInternalRecursive<Boundable, TrunkSIMDHelperFallback, Func>(this->tree.baseTrunk, this->tree.baseTrunkSize, func);
}
template<typename Func>
void forEachColissionWith(const BoundsTree& other, const Func& func) const {
if(this->tree.baseTrunkSize == 0 || other.tree.baseTrunkSize == 0) return;
forEachColissionBetweenRecursive<Boundable, TrunkSIMDHelperFallback, Func>(this->tree.baseTrunk, this->tree.baseTrunkSize, other.tree.baseTrunk, other.tree.baseTrunkSize, func);
}
void recalculateBounds() {
recalculateBoundsRecursive<Boundable>(this->tree.baseTrunk, this->tree.baseTrunkSize);
}
void improveStructure() { tree.improveStructure(); }
void maxImproveStructure() { tree.maxImproveStructure(); }
};
struct BasicBounded {
BoundsTemplate<float> bounds;
BoundsTemplate<float> getBounds() const { return bounds; }
};
};
================================================
FILE: Physics3D/boundstree/boundsTreeAVX.cpp
================================================
#include "boundsTree.h"
#include "../datastructures/alignedPtr.h"
#include <immintrin.h>
namespace P3D {
OverlapMatrix TrunkSIMDHelperFallback::computeBoundsOverlapMatrixAVX(const TreeTrunk& trunkA, int trunkASize, const TreeTrunk& trunkB, int trunkBSize) {
OverlapMatrix result;
__m256 rx0 = _mm256_set1_ps(0);
__m256 ry0 = _mm256_set1_ps(0);
__m256 rz0 = _mm256_set1_ps(0);
__m256 rx1 = _mm256_set1_ps(0);
__m256 ry1 = _mm256_set1_ps(0);
__m256 rz1 = _mm256_set1_ps(0);
alignas(32) float tempBuff[8];
__m256 bxmin = _mm256_load_ps(trunkB.subNodeBounds.xMin);
__m256 bymin = _mm256_load_ps(trunkB.subNodeBounds.yMin);
__m256 bzmin = _mm256_load_ps(trunkB.subNodeBounds.zMin);
__m256 bxmax = _mm256_load_ps(trunkB.subNodeBounds.xMax);
__m256 bymax = _mm256_load_ps(trunkB.subNodeBounds.yMax);
__m256 bzmax = _mm256_load_ps(trunkB.subNodeBounds.zMax);
for(int a = 0; a < trunkASize; a++) {
BoundsTemplate<float> aBounds0 = trunkA.getBoundsOfSubNode(a);
__m256 axmin = _mm256_set1_ps(aBounds0.min.x);
__m256 aymin = _mm256_set1_ps(aBounds0.min.y);
__m256 azmin = _mm256_set1_ps(aBounds0.min.z);
__m256 axmax = _mm256_set1_ps(aBounds0.max.x);
__m256 aymax = _mm256_set1_ps(aBounds0.max.y);
__m256 azmax = _mm256_set1_ps(aBounds0.max.z);
rx0 = _mm256_cmp_ps(axmax, bxmin, _CMP_GE_OQ);
ry0 = _mm256_cmp_ps(aymax, bymin, _CMP_GE_OQ);
rz0 = _mm256_cmp_ps(azmax, bzmin, _CMP_GE_OQ);
rx1 = _mm256_cmp_ps(axmin, bxmax, _CMP_LE_OQ);
ry1 = _mm256_cmp_ps(aymin, bymax, _CMP_LE_OQ);
rz1 = _mm256_cmp_ps(azmin, bzmax, _CMP_LE_OQ);
__m256 resultBool = _mm256_and_ps( _mm256_and_ps(_mm256_and_ps(rx0, ry0), rz0),
_mm256_and_ps( _mm256_and_ps(rx1, ry1), rz1) );
_mm256_store_ps(tempBuff, resultBool);
result[a][0] = tempBuff[0];
result[a][1] = tempBuff[1];
result[a][2] = tempBuff[2];
result[a][3] = tempBuff[3];
result[a][4] = tempBuff[4];
result[a][5] = tempBuff[5];
result[a][6] = tempBuff[6];
result[a][7] = tempBuff[7];
}
return result;
}
}
================================================
FILE: Physics3D/boundstree/boundsTreeSSE.cpp
================================================
#include "boundsTree.h"
#include "../datastructures/alignedPtr.h"
#include <immintrin.h>
namespace P3D {
OverlapMatrix TrunkSIMDHelperFallback::computeBoundsOverlapMatrixSSE(const TreeTrunk& trunkA, int trunkASize, const TreeTrunk& trunkB, int trunkBSize) {
OverlapMatrix result;
__m128 rx0 = _mm_set1_ps(0);
__m128 ry0 = _mm_set1_ps(0);
__m128 rz0 = _mm_set1_ps(0);
__m128 rx1 = _mm_set1_ps(0);
__m128 ry1 = _mm_set1_ps(0);
__m128 rz1 = _mm_set1_ps(0);
alignas(32) float tempBuff[4];
for(int a = 0; a < trunkASize; a++) {
BoundsTemplate<float> aBounds0 = trunkA.getBoundsOfSubNode(a);
__m128 axmin = _mm_set1_ps(aBounds0.min.x);
__m128 aymin = _mm_set1_ps(aBounds0.min.y);
__m128 azmin = _mm_set1_ps(aBounds0.min.z);
__m128 axmax = _mm_set1_ps(aBounds0.max.x);
__m128 aymax = _mm_set1_ps(aBounds0.max.y);
__m128 azmax = _mm_set1_ps(aBounds0.max.z);
for(unsigned short int i=0; i<2; i++){
__m128 bxmin = _mm_load_ps(trunkB.subNodeBounds.xMin + i * 4);
__m128 bymin = _mm_load_ps(trunkB.subNodeBounds.yMin + i * 4);
__m128 bzmin = _mm_load_ps(trunkB.subNodeBounds.zMin + i * 4);
__m128 bxmax = _mm_load_ps(trunkB.subNodeBounds.xMax + i * 4);
__m128 bymax = _mm_load_ps(trunkB.subNodeBounds.yMax + i * 4);
__m128 bzmax = _mm_load_ps(trunkB.subNodeBounds.zMax + i * 4);
rx0 = _mm_cmp_ps(axmax, bxmin, _CMP_GE_OQ);
ry0 = _mm_cmp_ps(aymax, bymin, _CMP_GE_OQ);
rz0 = _mm_cmp_ps(azmax, bzmin, _CMP_GE_OQ);
rx1 = _mm_cmp_ps(axmin, bxmax, _CMP_LE_OQ);
ry1 = _mm_cmp_ps(aymin, bymax, _CMP_LE_OQ);
rz1 = _mm_cmp_ps(azmin, bzmax, _CMP_LE_OQ);
__m128 resultBool = _mm_and_ps( _mm_and_ps(_mm_and_ps(rx0, ry0), rz0),
_mm_and_ps( _mm_and_ps(rx1, ry1), rz1) );
_mm_store_ps(tempBuff, resultBool);
result[a][0 + i * 4] = tempBuff[0];
result[a][1 + i * 4] = tempBuff[1];
result[a][2 + i * 4] = tempBuff[2];
result[a][3 + i * 4] = tempBuff[3];
}
}
return result;
}
}
================================================
FILE: Physics3D/boundstree/filters/outOfBoundsFilter.h
================================================
#pragma once
#include "../../math/bounds.h"
#include "../boundsTree.h"
#include "../../part.h"
namespace P3D {
struct OutOfBoundsFilter {
Bounds bounds;
OutOfBoundsFilter() = default;
OutOfBoundsFilter(const Bounds& bounds) : bounds(bounds) {}
std::array<bool, BRANCH_FACTOR> operator()(const TreeTrunk& trunk, int trunkSize) const {
std::array<bool, BRANCH_FACTOR> results;
for(int i = 0; i < trunkSize; i++) {
results[i] = !this->bounds.contains(trunk.getBoundsOfSubNode(i));
}
return results;
}
bool operator()(const Part& part) const {
return true;
}
};
};
================================================
FILE: Physics3D/boundstree/filters/rayIntersectsBoundsFilter.h
================================================
#pragma once
#include "../../math/bounds.h"
#include "../../math/ray.h"
#include "../../part.h"
#include "../boundsTree.h"
namespace P3D {
struct RayIntersectBoundsFilter {
Ray ray;
RayIntersectBoundsFilter() = default;
RayIntersectBoundsFilter(const Ray& ray) : ray(ray) {}
std::array<bool, BRANCH_FACTOR> operator()(const TreeTrunk& trunk, int trunkSize) const {
std::array<bool, BRANCH_FACTOR> results;
for(int i = 0; i < trunkSize; i++) {
results[i] = doRayAndBoundsIntersect(trunk.getBoundsOfSubNode(i), this->ray);
}
return results;
}
bool operator()(const Part& part) const {
return true;
}
};
};
================================================
FILE: Physics3D/boundstree/filters/visibilityFilter.cpp
================================================
#include "visibilityFilter.h"
#include "../../math/linalg/trigonometry.h"
#include "../../math/position.h"
#include "../../math/bounds.h"
#include "../../part.h"
namespace P3D {
VisibilityFilter::VisibilityFilter(const Position& origin, Vec3 normals[5], double maxDepth) :
origin(origin),
up(normals[0]), down(normals[1]), left(normals[2]), right(normals[3]), forward(normals[4]),
maxDepth(maxDepth) {}
VisibilityFilter VisibilityFilter::fromSteps(const Position& origin, const Vec3& stepForward, const Vec3& stepUp, const Vec3& stepRight, double maxDepth) {
Vec3 upNormal = (stepForward + stepUp) % stepRight;
Vec3 downNormal = -(stepForward - stepUp) % stepRight;
Vec3 leftNormal = -(stepForward + stepRight) % stepUp;
Vec3 rightNormal = (stepForward - stepRight) % stepUp;
Vec3 normals[5]{upNormal, downNormal, leftNormal, rightNormal, stepForward};
return VisibilityFilter(origin, normals, maxDepth);
}
VisibilityFilter VisibilityFilter::fromSteps(const Position& origin, const Vec3& stepForward, const Vec3& stepUp, const Vec3& stepRight, double maxDepth, double left, double right, double down, double up) {
Vec3 upNormal = (stepForward + stepUp * up) % stepRight;
Vec3 downNormal = -(stepForward + stepUp * down) % stepRight;
Vec3 leftNormal = -(stepForward - stepRight * left) % stepUp;
Vec3 rightNormal = (stepForward - stepRight * right) % stepUp;
Vec3 normals[5]{upNormal, downNormal, leftNormal, rightNormal, stepForward};
return VisibilityFilter(origin, normals, maxDepth);
}
VisibilityFilter VisibilityFilter::forWindow(const Position& origin, const Vec3& cameraForward, const Vec3& cameraUp, double fov, double aspect, double maxDepth) {
double tanFov = tan(fov / 2);
Vec3 stepForward = normalize(cameraForward);
Vec3 stepUp = normalize(cameraUp) * tanFov;
Vec3 stepRight = normalize(cameraUp % cameraForward) * tanFov * aspect;
return fromSteps(
origin,
stepForward,
stepUp,
stepRight,
maxDepth
);
}
VisibilityFilter VisibilityFilter::forSubWindow(const Position& origin, const Vec3& cameraForward, const Vec3& cameraUp, double fov, double aspect, double maxDepth, double left, double right, double down, double up) {
double tanFov = tan(fov / 2);
Vec3 stepForward = normalize(cameraForward);
Vec3 stepUp = normalize(cameraUp) * tanFov;
Vec3 stepRight = normalize(cameraUp % cameraForward) * tanFov * aspect;
return fromSteps(
origin,
stepForward,
stepUp,
stepRight,
maxDepth,
left, right, down, up
);
}
bool VisibilityFilter::operator()(const Position& point) const {
double offsets[5]{0,0,0,0,maxDepth};
Vec3 normals[5]{up, down, left, right, forward};
for(int i = 0; i < 5; i++) {
Vec3& normal = normals[i];
Vec3 relativePos = point - origin;
if(relativePos * normal > offsets[i])
return false;
}
return true;
}
bool VisibilityFilter::operator()(const Bounds& bounds) const {
double offsets[5]{0,0,0,0,maxDepth};
Vec3 normals[5]{up, down, left, right, forward};
for(int i = 0; i < 5; i++) {
Vec3& normal = normals[i];
// we're checking that *a* corner of the TreeNode's bounds is within the viewport, basically similar to rectangle-rectangle colissions, google it!
// cornerOfInterest is the corner that is the furthest positive corner relative to the normal, so if it is not visible (eg above the normal) then the whole box must be invisible
Position cornerOfInterest(
(normal.x >= 0) ? bounds.min.x : bounds.max.x,
(normal.y >= 0) ? bounds.min.y : bounds.max.y, // let's look at the top of the viewport, if the bottom of the box is above this then the whole box must be above it.
(normal.z >= 0) ? bounds.min.z : bounds.max.z
);
Vec3 relativePos = cornerOfInterest - origin;
if(relativePos * normal > offsets[i])
return false;
}
return true;
}
bool VisibilityFilter::operator()(const Part& part) const {
return true;
}
};
/* A
/
/ o---o <-- cornerOfInterest for B
/ | |
/ | |
o o---o <-- cornerOfInterest for A
\
\
\
\
B
A B
\ COI B /
\ v /
\ o---o <- COI A
\ |/ |
\ | |
\ /o---o
\ /
o
*/
================================================
FILE: Physics3D/boundstree/filters/visibilityFilter.h
================================================
#pragma once
#include "../../math/linalg/vec.h"
#include "../../math/bounds.h"
#include "../../part.h"
namespace P3D {
class VisibilityFilter {
public:
Position origin;
private:
// normals of the viewPort, facing outward
Vec3 up;
Vec3 down;
Vec3 left;
Vec3 right;
Vec3 forward;
double maxDepth;
public:
VisibilityFilter() : up(), down(), left(), right(), forward(), maxDepth() {};
VisibilityFilter(const Position& origin, Vec3 normals[5], double maxDepth);
/*
Creates a VisibilityFilter from the values derived from usual camera parameters.
stepForward: the direction of the camera
stepUp: should be perpendicular to stepForward & stepRight, furthest visible point, starting from stepForward, in the up direction.
stepRight: should be perpendicular to stepForward & stepUp, furthest visible point, starting from stepForward, in the right direction.
*/
static VisibilityFilter fromSteps(const Position& origin, const Vec3& stepForward, const Vec3& stepUp, const Vec3& stepRight, double maxDepth);
/*
Creates a VisibilityFilter from the values derived from common camera parameters.
cameraForward: the direction of the camera
cameraUp: should be perpendicular to cameraForward & cameraRight, furthest visible point, starting from cameraForward, in the up direction.
cameraRight: should be perpendicular to cameraForward & cameraUp, furthest visible point, starting from cameraForward, in the right direction.
Also accepts subWindow parameters:
left-right goes from -1..1
down-up goes from -1..1
*/
static VisibilityFilter fromSteps(const Position& origin, const Vec3& stepForward, const Vec3& stepUp, const Vec3& stepRight, double maxDepth, double left, double right, double down, double up);
/*
Creates a VisibilityFilter from the values derived from usual camera parameters.
cameraForward: the direction of the camera
cameraUp: should be perpendicular to cameraForward, up direction relative to the camera
fov: Field Of View of the camera, expressed in radians
aspect: aspect ratio of the camera, == width / height
*/
static VisibilityFilter forWindow(const Position& origin, const Vec3& cameraForward, const Vec3& cameraUp, double fov, double aspect, double maxDepth);
/*
Creates a VisibilityFilter for a subregion of the screen. Useful for selection and stuff
Create it by giving the same arguments as forWindow, but also pass which portion of the screen to select.
left-right goes from -1..1
down-up goes from -1..1
*/
static VisibilityFilter forSubWindow(const Position& origin, const Vec3& cameraForward, const Vec3& cameraUp, double fov, double aspect, double maxDepth, double left, double right, double down, double up);
bool operator()(const Position& point) const;
bool operator()(const Part& part) const;
bool operator()(const Bounds& bounds) const;
Vec3 getForwardStep() const { return forward; }
Vec3 getTopOfViewPort() const { return projectToPlaneNormal(forward, up); }
Vec3 getBottomOfViewPort() const { return projectToPlaneNormal(forward, down); }
Vec3 getLeftOfViewPort() const { return projectToPlaneNormal(forward, left); }
Vec3 getRightOfViewPort() const { return projectToPlaneNormal(forward, right); }
};
};
================================================
FILE: Physics3D/colissionBuffer.h
================================================
#pragma once
#include <vector>
namespace P3D {
struct Colission {
Part* p1;
Part* p2;
Position intersection;
Vec3 exitVector;
};
struct ColissionBuffer {
std::vector<Colission> freePartColissions;
std::vector<Colission> freeTerrainColissions;
inline void addFreePartColission(Part* a, Part* b, Position intersection, Vec3 exitVector) {
freePartColissions.push_back(Colission{a, b, intersection, exitVector});
}
inline void addTerrainColission(Part* freePart, Part* terrainPart, Position intersection, Vec3 exitVector) {
freeTerrainColissions.push_back(Colission{freePart, terrainPart, intersection, exitVector});
}
inline void clear() {
freePartColissions.clear();
freeTerrainColissions.clear();
}
};
};
================================================
FILE: Physics3D/constraints/ballConstraint.cpp
================================================
#include "ballConstraint.h"
#include "constraintImpl.h"
namespace P3D {
int BallConstraint::maxNumberOfParameters() const {
return 3;
}
static ConstraintMatrixPair<3> makeMatrices(const PhysicalInfo& phys, const Vec3& attach) {
Vec3 attachRelativeToCOM = phys.cframe.localToRelative(attach) - phys.relativeCenterOfMass;
Mat3 crossEquivAttach = createCrossProductEquivalent(attachRelativeToCOM);
Matrix<double, 6, 3> parameterToMotion = joinVertical(Mat3::DIAGONAL(phys.forceResponse), phys.momentResponse * crossEquivAttach);
Matrix<double, 3, 6> motionToEquation = joinHorizontal(Mat3::IDENTITY(), -crossEquivAttach);
return ConstraintMatrixPair<3>{parameterToMotion, motionToEquation};
}
ConstraintMatrixPack BallConstraint::getMatrices(const PhysicalInfo& physA, const PhysicalInfo& physB, double* matrixBuf, double* errorBuf) const {
ConstraintMatrixPair<3> cA = makeMatrices(physA, attachA);
ConstraintMatrixPair<3> cB = makeMatrices(physB, attachB);
Vec3 error0 = physB.cframe.localToGlobal(attachB) - physA.cframe.localToGlobal(attachA);
Vec3 velocityA = cA.motionToEquation * physA.motion.getDerivAsVec6(0);
Vec3 velocityB = cB.motionToEquation * physB.motion.getDerivAsVec6(0);
Vec3 error1 = velocityB - velocityA;
Matrix<double, 3, NUMBER_OF_ERROR_DERIVATIVES> error = Matrix<double, 3, NUMBER_OF_ERROR_DERIVATIVES>::fromColumns({error0, error1});
/*inMemoryMatrixVectorMultiply(motionToEquationMatrixA, getMotionVecForDeriv(physA.mainPhysical->motionOfCenterOfMass, 1), mA);
inMemoryMatrixVectorMultiply(motionToEquationMatrixB, getMotionVecForDeriv(physB.mainPhysical->motionOfCenterOfMass, 1), mB);
mB -= mA;
errorValue.setCol(2, mB);*/
return ConstraintMatrixPack(matrixBuf, errorBuf, cA, cB, error);
}
};
================================================
FILE: Physics3D/constraints/ballConstraint.h
================================================
#pragma once
#include "../math/linalg/vec.h"
#include "constraint.h"
namespace P3D {
struct BallConstraint : public Constraint {
Vec3 attachA;
Vec3 attachB;
BallConstraint() = default;
inline BallConstraint(Vec3 attachA, Vec3 attachB) :
attachA(attachA), attachB(attachB) {}
virtual int maxNumberOfParameters() const override;
virtual ConstraintMatrixPack getMatrices(const PhysicalInfo& physA, const PhysicalInfo& physB, double* matrixBuf, double* errorBuf) const override;
};
};
================================================
FILE: Physics3D/constraints/barConstraint.cpp
================================================
#include "barConstraint.h"
#include "constraintImpl.h"
namespace P3D {
int BarConstraint::maxNumberOfParameters() const {
return 1;
}
static ConstraintMatrixPair<1> makeMatrices(const PhysicalInfo& phys, const Vec3& attach, const Vec3& barAxis) {
Vec3 attachRelativeToCOM = phys.cframe.localToRelative(attach) - phys.relativeCenterOfMass;
Mat3 crossEquivAttach = createCrossProductEquivalent(attachRelativeToCOM);
Matrix<double, 6, 1> parameterToMotion = Matrix<double, 6, 1>::fromColumns({join(phys.forceResponse * barAxis, phys.momentResponse * crossEquivAttach * barAxis)});
Matrix<double, 1, 6> motionToEquation = Matrix<double, 1, 6>::fromRows({join(barAxis, (attachRelativeToCOM % barAxis))});
return ConstraintMatrixPair<1>{parameterToMotion, motionToEquation};
}
ConstraintMatrixPack BarConstraint::getMatrices(const PhysicalInfo& physA, const PhysicalInfo& physB, double* matrixBuf, double* errorBuf) const {
Vec3 barAxis = physB.cframe.localToGlobal(attachB) - physA.cframe.localToGlobal(attachA);
ConstraintMatrixPair<1> cA = makeMatrices(physA, attachA, barAxis);
ConstraintMatrixPair<1> cB = makeMatrices(physB, attachB, barAxis);
double error0 = length(barAxis) - this->barLength;
double velocityA = cA.motionToEquation * physA.motion.getDerivAsVec6(0);
double velocityB = cB.motionToEquation * physB.motion.getDerivAsVec6(0);
double error1 = velocityB - velocityA;
Matrix<double, 1, NUMBER_OF_ERROR_DERIVATIVES> error = Matrix<double, 1, NUMBER_OF_ERROR_DERIVATIVES>::fromColumns({error0, error1});
/*inMemoryMatrixVectorMultiply(motionToEquationMatrixA, getMotionVecForDeriv(physA.mainPhysical->motionOfCenterOfMass, 1), mA);
inMemoryMatrixVectorMultiply(motionToEquationMatrixB, getMotionVecForDeriv(physB.mainPhysical->motionOfCenterOfMass, 1), mB);
mB -= mA;
errorValue.setCol(2, mB);*/
return ConstraintMatrixPack(matrixBuf, errorBuf, cA, cB, error);
}
};
================================================
FILE: Physics3D/constraints/barConstraint.h
================================================
#pragma once
#include "../math/linalg/vec.h"
#include "constraint.h"
namespace P3D {
struct BarConstraint : public Constraint {
Vec3 attachA;
Vec3 attachB;
double barLength;
BarConstraint() = default;
inline BarConstraint(Vec3 attachA, Vec3 attachB, double barLength) :
attachA(attachA), attachB(attachB), barLength(barLength) {}
virtual int maxNumberOfParameters() const override;
virtual ConstraintMatrixPack getMatrices(const PhysicalInfo& physA, const PhysicalInfo& physB, double* matrixBuf, double* errorBuf) const override;
};
};
================================================
FILE: Physics3D/constraints/constraint.cpp
================================================
#include "constraint.h"
namespace P3D {
Constraint::~Constraint() {}
}
================================================
FILE: Physics3D/constraints/constraint.h
================================================
#pragma once
namespace P3D {
class ConstraintMatrixPack;
struct PhysicalInfo;
struct Constraint {
virtual int maxNumberOfParameters() const = 0;
virtual ConstraintMatrixPack getMatrices(const PhysicalInfo& physA, const PhysicalInfo& physB, double* matrixBuf, double* errorBuf) const = 0;
virtual ~Constraint();
};
}
================================================
FILE: Physics3D/constraints/constraintGroup.cpp
================================================
#include "constraintGroup.h"
#include "constraintImpl.h"
#include "../math/linalg/largeMatrix.h"
#include "../math/linalg/largeMatrixAlgorithms.h"
#include "../math/linalg/mat.h"
#include "../physical.h"
#include "../math/mathUtil.h"
#include "../misc/validityHelper.h"
#include <fstream>
#include <cstddef>
#include <map>
namespace P3D {
int PhysicalConstraint::maxNumberOfParameters() const {
return constraint->maxNumberOfParameters();
}
static PhysicalInfo getInfo(const Physical& phys) {
GlobalCFrame cf = phys.getCFrame();
Vec3 relativeCOM = phys.mainPhysical->totalCenterOfMass - (cf.getPosition() - phys.mainPhysical->getCFrame().getPosition());
return PhysicalInfo{cf, phys.getMotion(), 1 / phys.mainPhysical->totalMass, phys.mainPhysical->momentResponse, relativeCOM};
}
ConstraintMatrixPack PhysicalConstraint::getMatrices(double* matrixBuf, double* errorBuf) const {
PhysicalInfo infoA = getInfo(*physA);
PhysicalInfo infoB = getInfo(*physB);
return constraint->getMatrices(infoA, infoB, matrixBuf, errorBuf);
}
void ConstraintGroup::add(Physical* first, Physical* second, Constraint* constraint) {
this->constraints.push_back(PhysicalConstraint(first, second, constraint));
}
void ConstraintGroup::add(Part* first, Part* second, Constraint* constraint) {
this->constraints.push_back(PhysicalConstraint(first->ensureHasPhysical(), second->ensureHasPhysical(), constraint));
}
void ConstraintGroup::apply() const {
std::size_t maxNumberOfParameters = 0;
ConstraintMatrixPack* constraintMatrices = new ConstraintMatrixPack[constraints.size()];
for(std::size_t i = 0; i < constraints.size(); i++) {
maxNumberOfParameters += constraints[i].constraint->maxNumberOfParameters();
}
double* matrixBuffer = new double[std::size_t(24) * maxNumberOfParameters];
double* errorBuffer = new double[std::size_t(NUMBER_OF_ERROR_DERIVATIVES) * maxNumberOfParameters];
std::size_t numberOfParams = 0;
for(std::size_t i = 0; i < constraints.size(); i++) {
constraintMatrices[i] = constraints[i].getMatrices(matrixBuffer + std::size_t(24) * numberOfParams, errorBuffer + std::size_t(NUMBER_OF_ERROR_DERIVATIVES) * numberOfParams);
numberOfParams += constraintMatrices[i].getSize();
}
UnmanagedHorizontalFixedMatrix<double, NUMBER_OF_ERROR_DERIVATIVES> vectorToSolve(errorBuffer, maxNumberOfParameters);
LargeMatrix<double> systemToSolve(numberOfParams, numberOfParams);
{
std::size_t curColIndex = 0;
for(std::size_t blockCol = 0; blockCol < constraints.size(); blockCol++) {
int colSize = constraintMatrices[blockCol].getSize();
MotorizedPhysical* mPhysA = constraints[blockCol].physA->mainPhysical;
MotorizedPhysical* mPhysB = constraints[blockCol].physB->mainPhysical;
const UnmanagedHorizontalFixedMatrix<double, 6> motionToEq1 = constraintMatrices[blockCol].getMotionToEquationMatrixA();
const UnmanagedHorizontalFixedMatrix<double, 6> motionToEq2 = constraintMatrices[blockCol].getMotionToEquationMatrixB();
std::size_t curRowIndex = 0;
for(std::size_t blockRow = 0; blockRow < constraints.size(); blockRow++) {
int rowSize = constraintMatrices[blockRow].getSize();
MotorizedPhysical* cPhysA = constraints[blockRow].physA->mainPhysical;
MotorizedPhysical* cPhysB = constraints[blockRow].physB->mainPhysical;
const UnmanagedVerticalFixedMatrix<double, 6> paramToMotion1 = constraintMatrices[blockRow].getParameterToMotionMatrixA();
const UnmanagedVerticalFixedMatrix<double, 6> paramToMotion2 = constraintMatrices[blockRow].getParameterToMotionMatrixB();
double resultBuf1[6 * 6]; UnmanagedLargeMatrix<double> resultMat1(resultBuf1, rowSize, colSize);
for(double& d : resultMat1) d = 0.0;
double resultBuf2[6 * 6]; UnmanagedLargeMatrix<double> resultMat2(resultBuf2, rowSize, colSize);
for(double& d : resultMat2) d = 0.0;
if(mPhysA == cPhysA) {
inMemoryMatrixMultiply(motionToEq1, paramToMotion1, resultMat1);
} else if(mPhysA == cPhysB) {
inMemoryMatrixMultiply(motionToEq1, paramToMotion2, resultMat1);
inMemoryMatrixNegate(resultMat1);
}
if(mPhysB == cPhysA) {
inMemoryMatrixMultiply(motionToEq2, paramToMotion1, resultMat2);
inMemoryMatrixNegate(resultMat2);
} else if(mPhysB == cPhysB) {
inMemoryMatrixMultiply(motionToEq2, paramToMotion2, resultMat2);
}
resultMat1 += resultMat2;
systemToSolve.setSubMatrix(curColIndex, curRowIndex, resultMat1);
curRowIndex += rowSize;
}
curColIndex += colSize;
}
}
assert(isMatValid(vectorToSolve));
destructiveSolve(systemToSolve, vectorToSolve);
assert(isMatValid(vectorToSolve));
{
std::size_t curParameterIndex = 0;
for(std::size_t i = 0; i < constraints.size(); i++) {
const UnmanagedVerticalFixedMatrix<double, 6> curP2MA = constraintMatrices[i].getParameterToMotionMatrixA();
const UnmanagedVerticalFixedMatrix<double, 6> curP2MB = constraintMatrices[i].getParameterToMotionMatrixB();
std::size_t curSize = curP2MA.cols;
UnmanagedHorizontalFixedMatrix<double, NUMBER_OF_ERROR_DERIVATIVES> parameterVec = vectorToSolve.subRows(curParameterIndex, curSize);
Matrix<double, 6, NUMBER_OF_ERROR_DERIVATIVES> effectOnA = curP2MA * parameterVec;
Matrix<double, 6, NUMBER_OF_ERROR_DERIVATIVES> effectOnB = -(curP2MB * parameterVec);
// TODO add moving correction
Vector<double, 6> offsetAngularEffectOnA = effectOnA.getCol(0);
Vector<double, 6> offsetAngularEffectOnB = effectOnB.getCol(0);
assert(isVecValid(offsetAngularEffectOnA));
assert(isVecValid(offsetAngularEffectOnB));
GlobalCFrame& mainPACF = constraints[i].physA->mainPhysical->rigidBody.mainPart->cframe;
GlobalCFrame& mainPBCF = constraints[i].physB->mainPhysical->rigidBody.mainPart->cframe;
mainPACF.position += offsetAngularEffectOnA.getSubVector<3>(0);
mainPACF.rotation = Rotation::fromRotationVector(offsetAngularEffectOnA.getSubVector<3>(3)) * mainPACF.rotation;
mainPBCF.position += offsetAngularEffectOnB.getSubVector<3>(0);
mainPBCF.rotation = Rotation::fromRotationVector(offsetAngularEffectOnB.getSubVector<3>(3)) * mainPBCF.rotation;
Vector<double, 6> velAngularEffectOnA = effectOnA.getCol(1);
Vector<double, 6> velAngularEffectOnB = effectOnB.getCol(1);
assert(isVecValid(velAngularEffectOnA));
assert(isVecValid(velAngularEffectOnB));
constraints[i].physA->mainPhysical->motionOfCenterOfMass.translation.translation[0] += velAngularEffectOnA.getSubVector<3>(0);
constraints[i].physA->mainPhysical->motionOfCenterOfMass.rotation.rotation[0] += velAngularEffectOnA.getSubVector<3>(3);
constraints[i].physB->mainPhysical->motionOfCenterOfMass.translation.translation[0] += velAngularEffectOnB.getSubVector<3>(0);
constraints[i].physB->mainPhysical->motionOfCenterOfMass.rotation.rotation[0] += velAngularEffectOnB.getSubVector<3>(3);
/*Vector<double, 6> accelAngularEffectOnA = effectOnA.getCol(2);
Vector<double, 6> accelAngularEffectOnB = effectOnB.getCol(2);
constraints[i].physA->mainPhysical->totalForce += constraints[i].physA->mainPhysical->totalMass * velAngularEffectOnA.getSubVector<3>(0);
constraints[i].physA->mainPhysical->totalMoment += ~constraints[i].physA->mainPhysical->momentResponse * velAngularEffectOnA.getSubVector<3>(3);
constraints[i].physB->mainPhysical->totalForce += constraints[i].physB->mainPhysical->totalMass * velAngularEffectOnB.getSubVector<3>(0);
constraints[i].physB->mainPhysical->totalMoment += ~constraints[i].physB->mainPhysical->momentResponse * velAngularEffectOnB.getSubVector<3>(3);*/
curParameterIndex += curSize;
}
assert(curParameterIndex == numberOfParams);
}
}
};
================================================
FILE: Physics3D/constraints/constraintGroup.h
================================================
#pragma once
#include <vector>
#include "constraint.h"
namespace P3D {
class Physical;
class Part;
class PhysicalConstraint {
public:
Physical* physA;
Physical* physB;
Constraint* constraint;
inline PhysicalConstraint(Physical* physA, Physical* physB, Constraint* constraint) :
physA(physA), physB(physB), constraint(constraint) {}
int maxNumberOfParameters() const;
ConstraintMatrixPack getMatrices(double* matrixBuf, double* errorBuf) const;
};
class ConstraintGroup {
public:
std::vector<PhysicalConstraint> constraints;
//std::vector<MotorizedPhysical*> physicals;
void add(Physical* first, Physical* second, Constraint* constraint);
void add(Part* first, Part* second, Constraint* constraint);
void apply() const;
};
}
================================================
FILE: Physics3D/constraints/constraintImpl.h
================================================
#pragma once
#include "constraint.h"
#include "../math/linalg/mat.h"
#include "../math/linalg/largeMatrix.h"
#include "../math/globalCFrame.h"
#include "../motion.h"
namespace P3D {
#define NUMBER_OF_ERROR_DERIVATIVES 2
template<std::size_t Size>
struct ConstraintMatrixPair {
Matrix<double, 6, Size> paramToMotion;
Matrix<double, Size, 6> motionToEquation;
ConstraintMatrixPair operator-() const {
return ConstraintMatrixPair{-paramToMotion, -motionToEquation};
}
};
struct PhysicalInfo {
GlobalCFrame cframe;
Motion motion;
double forceResponse; // 1/mass
Mat3 momentResponse;
Vec3 relativeCenterOfMass;
};
class ConstraintMatrixPack {
double* matrixData;
double* errorData;
int size; // size * 6 for matrix size, size * 6 * 4 for total size
public:
ConstraintMatrixPack() = default;
template<std::size_t Size>
ConstraintMatrixPack(double* matrixBuf, double* errorBuf,
const Matrix<double, 6, Size>& paramToMotionA,
const Matrix<double, 6, Size>& paramToMotionB,
const Matrix<double, Size, 6>& motionToEqA,
const Matrix<double, Size, 6>& motionToEqB,
const Matrix<double, Size, NUMBER_OF_ERROR_DERIVATIVES>& errorMat) : matrixData(matrixBuf), errorData(errorBuf), size(Size) {
paramToMotionA.toColMajorData(matrixData);
paramToMotionB.toColMajorData(matrixData + 6 * Size);
motionToEqA.toRowMajorData(matrixData + 12 * Size);
motionToEqB.toRowMajorData(matrixData + 18 * Size);
errorMat.toRowMajorData(errorData);
}
template<std::size_t Size>
ConstraintMatrixPack(double* matrixBuf, double* errorBuf,
const ConstraintMatrixPair<Size>& mA,
const ConstraintMatrixPair<Size>& mB,
const Matrix<double, Size, NUMBER_OF_ERROR_DERIVATIVES>& errorMat) : matrixData(matrixBuf), errorData(errorBuf), size(Size) {
mA.paramToMotion.toColMajorData(matrixData);
mB.paramToMotion.toColMajorData(matrixData + 6 * Size);
mA.motionToEquation.toRowMajorData(matrixData + 12 * Size);
mB.motionToEquation.toRowMajorData(matrixData + 18 * Size);
errorMat.toRowMajorData(errorData);
}
int getSize() const { return size; }
UnmanagedVerticalFixedMatrix<double, 6> getParameterToMotionMatrixA() const {
return UnmanagedVerticalFixedMatrix<double, 6>(matrixData, size);
}
UnmanagedVerticalFixedMatrix<double, 6> getParameterToMotionMatrixB() const {
return UnmanagedVerticalFixedMatrix<double, 6>(matrixData + size_t(6) * size, size);
}
UnmanagedHorizontalFixedMatrix<double, 6> getMotionToEquationMatrixA() const {
return UnmanagedHorizontalFixedMatrix<double, 6>(matrixData + size_t(12) * size, size);
}
UnmanagedHorizontalFixedMatrix<double, 6> getMotionToEquationMatrixB() const {
return UnmanagedHorizontalFixedMatrix<double, 6>(matrixData + size_t(18) * size, size);
}
UnmanagedHorizontalFixedMatrix<double, NUMBER_OF_ERROR_DERIVATIVES> getErrorMatrix() const {
return UnmanagedHorizontalFixedMatrix<double, NUMBER_OF_ERROR_DERIVATIVES>(errorData, size);
}
};
}
================================================
FILE: Physics3D/constraints/hingeConstraint.cpp
================================================
#include "hingeConstraint.h"
#include "constraintImpl.h"
namespace P3D {
int HingeConstraint::maxNumberOfParameters() const {
return 5;
}
static ConstraintMatrixPair<5> makeMatrices(const PhysicalInfo& phys, const Vec3& attach, const Vec3& p1, const Vec3& p2) {
Vec3 attachRelativeToCOM = phys.cframe.localToRelative(attach) - phys.relativeCenterOfMass;
Mat3 crossEquivAttach = createCrossProductEquivalent(attachRelativeToCOM);
Matrix<double, 3, 5> impulseToMotion = joinHorizontal(Mat3::DIAGONAL(phys.forceResponse), Matrix<double, 3, 2>::ZEROS());
Matrix<double, 3, 5> angularEffect = joinHorizontal(crossEquivAttach, Matrix<double, 3, 2>::fromColumns({p1, p2}));
Matrix<double, 6, 5> parameterToMotion = joinVertical(impulseToMotion, phys.momentResponse * angularEffect);
Matrix<double, 5, 6> motionToEquation = join(Mat3::IDENTITY(), -crossEquivAttach, Matrix<double, 2, 3>::ZEROS(), Matrix<double, 2, 3>::fromRows({p1, p2}));
return ConstraintMatrixPair<5>{parameterToMotion, motionToEquation};
}
ConstraintMatrixPack HingeConstraint::getMatrices(const PhysicalInfo& physA, const PhysicalInfo& physB, double* matrixBuf, double* errorBuf) const {
Vec3 localMainAxis = normalize(this->axisA);
Vec3 localP1 = normalize(getPerpendicular(localMainAxis));
Vec3 localP2 = normalize(localMainAxis % localP1);
Vec3 localMainOffsetAxis = normalize(this->axisB);
Vec3 mainAxis = physA.cframe.localToRelative(localMainAxis);
Vec3 p1 = physA.cframe.localToRelative(localP1);
Vec3 p2 = physA.cframe.localToRelative(localP2);
Vec3 mainOffsetAxis = physB.cframe.localToRelative(localMainOffsetAxis);
// rotationOffset will be in the plane defined by p1 and p2, as it is perpendicular to mainAxis
Vec3 rotationOffset = mainAxis % mainOffsetAxis;
double rotationOffsetP1 = p1 * rotationOffset;
double rotationOffsetP2 = p2 * rotationOffset;
ConstraintMatrixPair<5> cA = makeMatrices(physA, attachA, p1, p2);
ConstraintMatrixPair<5> cB = makeMatrices(physB, attachB, p1, p2);
Vec5 error0 = join(Vec3(physB.cframe.localToGlobal(attachB) - physA.cframe.localToGlobal(attachA)), Vec2(rotationOffsetP1, rotationOffsetP2));
Vec5 velocityA = cA.motionToEquation * physA.motion.getDerivAsVec6(0);
Vec5 velocityB = cB.motionToEquation * physB.motion.getDerivAsVec6(0);
Vec5 error1 = velocityB - velocityA;
Matrix<double, 5, NUMBER_OF_ERROR_DERIVATIVES> error = Matrix<double, 5, NUMBER_OF_ERROR_DERIVATIVES>::fromColumns({error0, error1});
return ConstraintMatrixPack(matrixBuf, errorBuf, cA, cB, error);
}
};
================================================
FILE: Physics3D/constraints/hingeConstraint.h
================================================
#pragma once
#include "../math/linalg/vec.h"
#include "constraint.h"
namespace P3D {
struct HingeConstraint : public Constraint {
Vec3 attachA;
Vec3 axisA;
Vec3 attachB;
Vec3 axisB;
HingeConstraint() = default;
inline HingeConstraint(Vec3 attachA, Vec3 axisA, Vec3 attachB, Vec3 axisB) :
attachA(attachA), axisA(axisA), attachB(attachB), axisB(axisB) {}
virtual int maxNumberOfParameters() const override;
virtual ConstraintMatrixPack getMatrices(const PhysicalInfo& physA, const PhysicalInfo& physB, double* matrixBuf, double* errorBuf) const override;
};
};
================================================
FILE: Physics3D/datastructures/alignedPtr.h
================================================
#pragma once
#include <utility>
#include <cstddef>
#include "aligned_alloc.h"
namespace P3D {
template<typename T>
class UniqueAlignedPointer {
T* data;
public:
UniqueAlignedPointer() : data(nullptr) {}
UniqueAlignedPointer(std::size_t size, std::size_t align = alignof(T)) :
data(static_cast<T*>(aligned_malloc(sizeof(T)* size, align))) {}
~UniqueAlignedPointer() {
aligned_free(static_cast<void*>(data));
}
inline T* get() const { return data; }
operator T* () const { return data; }
UniqueAlignedPointer(const UniqueAlignedPointer& other) = delete;
UniqueAlignedPointer& operator=(const UniqueAlignedPointer& other) = delete;
UniqueAlignedPointer(UniqueAlignedPointer&& other) noexcept : data(other.data) {
other.data = nullptr;
}
UniqueAlignedPointer& operator=(UniqueAlignedPointer&& other) noexcept {
std::swap(this->data, other.data);
return *this;
}
};
template<typename T>
class SharedAlignedPointer {
T* data;
std::size_t* refCount;
public:
SharedAlignedPointer() : data(nullptr), refCount(nullptr) {}
SharedAlignedPointer(std::size_t size, std::size_t align = alignof(T)) :
data(static_cast<T*>(aligned_malloc(sizeof(T)* size, align))),
refCount(new std::size_t(1)) {}
~SharedAlignedPointer() {
if(refCount != nullptr && --(*refCount) == 0) {
aligned_free(static_cast<void*>(data));
delete refCount;
}
}
inline T* get() const { return data; }
operator T* () const { return data; }
SharedAlignedPointer(const SharedAlignedPointer& other) : data(other.data), refCount(other.refCount) {
(*refCount)++;
}
SharedAlignedPointer& operator=(const SharedAlignedPointer& other) {
this->~SharedAlignedPointer();
this->data = other.data;
this->refCount = other.refCount;
(*refCount)++;
return *this;
}
SharedAlignedPointer(SharedAlignedPointer&& other) noexcept : data(other.data), refCount(other.refCount) {
other.data = nullptr;
other.refCount = nullptr;
}
SharedAlignedPointer& operator=(SharedAlignedPointer&& other) noexcept {
std::swap(this->data, other.data);
std::swap(this->refCount, other.refCount);
return *this;
}
};
};
================================================
FILE: Physics3D/datastructures/aligned_alloc.cpp
================================================
#include "aligned_alloc.h"
#include <malloc.h>
#include <stdlib.h>
namespace P3D {
void* aligned_malloc(size_t size, size_t align) {
#ifdef _MSC_VER
return _aligned_malloc(size, align);
#else
return aligned_alloc(align, size);
#endif
}
void aligned_free(void* ptr) {
#ifdef _MSC_VER
_aligned_free(ptr);
#else
free(ptr);
#endif
}
};
================================================
FILE: Physics3D/datastructures/aligned_alloc.h
================================================
#pragma once
#include <cstddef>
namespace P3D {
void* aligned_malloc(std::size_t size, std::size_t align);
void aligned_free(void* ptr);
};
================================================
FILE: Physics3D/datastructures/buffers.h
================================================
#pragma once
#include <assert.h>
#include "iteratorEnd.h"
namespace P3D {
inline unsigned long long nextPowerOf2(unsigned long long v) {
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v |= v >> 32;
return v + 1;
}
template<typename T>
struct ListIter {
T* start;
T* fin;
T* begin() const { return start; }
T* end() const { return fin; }
};
/*template<typename T>
struct ConstListIter {
const T* start;
const T* fin;
const T* begin() const { return start; }
const T* end() const { return fin; }
};*/
template<typename T>
struct ListOfPtrIter {
T* const* cur;
ListOfPtrIter() = default;
ListOfPtrIter(T* const* cur) : cur(cur) {}
T& operator*() const {
return **cur;
}
ListOfPtrIter& operator++() {
cur++;
return *this;
}
ListOfPtrIter operator++(int) {
ListOfPtrIter prevSelf = *this;
cur++;
return prevSelf;
}
bool operator==(const ListOfPtrIter& other) const {
return this->cur == other.cur;
}
bool operator!=(const ListOfPtrIter& other) const {
return this->cur != other.cur;
}
T* operator->() const {
return *cur;
}
operator T* () const {
return *cur;
}
};
template<typename T>
struct ListOfPtrIterFactory {
T* const* start;
T* const* fin;
ListOfPtrIterFactory() {}
ListOfPtrIterFactory(T* const* start, T* const* fin) : start(start), fin(fin) {}
ListOfPtrIterFactory(const ListIter<T* const>& iter) : start(iter.start), fin(iter.fin) {}
ListOfPtrIterFactory(const ListIter<T*>& iter) : start(iter.start), fin(iter.fin) {}
ListOfPtrIter<T> begin() const { return ListOfPtrIter<T>{start}; }
ListOfPtrIter<T> end() const { return ListOfPtrIter<T>{fin}; }
};
template<typename T>
struct BufferWithCapacity {
T* data;
size_t capacity;
BufferWithCapacity() : data(nullptr), capacity(0) {};
BufferWithCapacity(size_t initialCapacity) : data(new T[initialCapacity]), capacity(initialCapacity) {}
BufferWithCapacity(BufferWithCapacity&& other) noexcept {
this->data = other.data;
this->capacity = other.capacity;
other.data = nullptr;
other.capacity = 0;
}
~BufferWithCapacity() {
delete[] data;
}
BufferWithCapacity(const BufferWithCapacity& other) = delete;
void operator=(const BufferWithCapacity& other) = delete;
BufferWithCapacity& operator=(BufferWithCapacity&& other) noexcept {
std::swap(this->data, other.data);
std::swap(this->capacity, other.capacity);
return *this;
}
void resize(size_t newCapacity, size_t sizeToCopy) {
T* newBuf = new T[newCapacity];
for(size_t i = 0; i < sizeToCopy; i++)
newBuf[i] = std::move(data[i]);
delete[] data;
data = newBuf;
capacity = newCapacity;
}
size_t ensureCapacity(size_t newCapacity, size_t sizeToCopy) {
if(newCapacity > this->capacity) {
size_t nextPower = nextPowerOf2(newCapacity);
resize(nextPower, sizeToCopy);
return nextPower;
}
return this->capacity;
}
T& operator[](size_t index) { return data[index]; }
const T& operator[](size_t index) const { return data[index]; }
};
template<typename T>
struct AddableBuffer : public BufferWithCapacity<T> {
size_t size = 0;
AddableBuffer() : BufferWithCapacity<T>() {}
AddableBuffer(size_t initialCapacity) : BufferWithCapacity<T>(initialCapacity) {}
AddableBuffer(T* data, size_t dataSize, size_t initialCapacity) : BufferWithCapacity<T>(initialCapacity), size(dataSize) {
assert(data != nullptr);
for(size_t i = 0; i < dataSize; i++)
this->data[i] = data[i];
}
~AddableBuffer() {}
AddableBuffer(const AddableBuffer<T>&) = delete;
AddableBuffer& operator=(const AddableBuffer<T>&) = delete;
AddableBuffer(AddableBuffer<T>&& other) noexcept : BufferWithCapacity<T>(std::move(other)), size(other.size) {
other.size = 0;
}
AddableBuffer<T>& operator=(AddableBuffer<T>&& other) noexcept {
BufferWithCapacity<T>::operator=(std::move(other));
size_t tmpSize = this->size;
this->size = other.size;
other.size = tmpSize;
return *this;
}
inline void resize(size_t newCapacity) {
BufferWithCapacity<T>::resize(newCapacity, this->size);
}
inline size_t ensureCapacity(size_t newCapacity) {
size_t newSize = BufferWithCapacity<T>::ensureCapacity(newCapacity, this->size);
return newSize;
}
inline T* add(const T& obj) {
this->ensureCapacity(this->size + 1);
this->data[this->size] = obj;
return &this->data[this->size++];
}
inline T* add(T&& obj) {
this->ensureCapacity(this->size + 1);
this->data[this->size] = std::move(obj);
return &this->data[this->size++];
}
inline void clear() {
size = 0;
}
inline T* begin() { return this->data; }
inline const T* begin() const { return this->data; }
inline T* end() { return this->data + size; }
inline const T* end() const { return this->data + this->size; }
inline bool liesInList(const T* obj) const {
return obj >= this->data && obj < this->data + this->size;
}
};
template<typename T, int N>
struct FixedLocalBuffer {
T buf[N]{};
int size = 0;
T& operator[](int index) { return buf[index]; }
const T& operator[](int index) const { return buf[index]; }
const T* begin() const { return &buf; }
T* begin() { return &buf; }
const T* end() const { return buf + size; }
T* end() { return buf + size; }
void add(const T& obj) {
buf[size++] = obj;
}
};
template<typename T>
struct CircularIter {
T* iter;
T* bufStart;
T* bufEnd;
size_t itemsLeft;
void operator++() {
iter++;
if(iter == bufEnd) {
iter = bufStart;
}
itemsLeft--;
}
T& operator*() const { return *iter; }
bool operator==(IteratorEnd) const {
return this->itemsLeft == 0;
}
bool operator!=(IteratorEnd) const {
return this->itemsLeft != 0;
}
};
template<typename T>
struct CircularBuffer {
private:
T* buf;
size_t curI = 0;
size_t capacity;
bool hasComeAround = false;
public:
CircularBuffer() : buf(nullptr), capacity(0) {}
CircularBuffer(size_t capacity) : buf(new T[capacity + 1]), capacity(capacity) {}
~CircularBuffer() { delete[] buf; }
inline size_t size() const {
if(hasComeAround)
return capacity;
else
return curI;
}
CircularBuffer(const CircularBuffer<T>& other) : buf(new T[other.capacity + 1]), curI(other.curI), capacity(other.capacity), hasComeAround(other.hasComeAround) {
for(size_t i = 0; i < other.capacity; i++) {
this->buf[i] = other.buf[i];
}
}
CircularBuffer& operator=(const CircularBuffer<T>& other) {
if(this->capacity != other.capacity) {
delete[] this->buf;
this->buf = new T[other.capacity];
}
this->curI = other.curI;
this->capacity = other.capacity;
this->hasComeAround = other.hasComeAround;
for(size_t i = 0; i < other.capacity; i++) {
this->buf[i] = other.buf[i];
}
return *this;
}
CircularBuffer(CircularBuffer<T>&& other) : buf(other.buf), curI(other.curI), capacity(other.capacity), hasComeAround(other.hasComeAround) {
other.buf = nullptr;
other.capacity = 0;
other.curI = 0;
other.hasComeAround = false;
}
CircularBuffer& operator=(CircularBuffer<T>&& other) {
std::swap(this->buf, other.buf);
std::swap(this->curI, other.curI);
std::swap(this->capacity, other.capacity);
std::swap(this->hasComeAround, other.hasComeAround);
return *this;
}
inline void add(const T& newObj) {
buf[curI] = newObj;
curI++;
if(curI >= capacity) {
curI = 0;
hasComeAround = true;
}
}
inline T sum() const {
size_t limit = size();
if(limit == 0)
return T();
T total = buf[0];
for(size_t i = 1; i < limit; i++)
total += buf[i];
return total;
}
inline T avg() const {
size_t limit = size();
if(limit == 0)
return T();
T total = sum();
return T(total / limit);
}
inline void resize(size_t newCapacity) {
T* newBuf = new T[newCapacity];
T* cur = newBuf;
size_t elementsForgotten = (this->capacity > newCapacity) ? this->capacity - newCapacity : 0;
if(hasComeAround) {
for(size_t i = curI + elementsForgotten; i < capacity; i++) {
*cur = buf[i];
cur++;
}
if(elementsForgotten > capacity - curI) {
elementsForgotten -= (capacity - curI);
}
}
for(size_t i = elementsForgotten; i < curI; i++) {
*cur = buf[i];
cur++;
}
delete[] buf;
this->buf = newBuf;
}
T& front() {
return (curI == 0) ? buf[capacity - 1] : buf[curI - 1];
}
const T& front() const {
return (curI == 0) ? buf[capacity - 1] : buf[curI - 1];
}
T& tail() {
return hasComeAround ? buf[curI] : buf[0];
}
const T& tail() const {
return hasComeAround ? buf[curI] : buf[0];
}
inline CircularIter<T> begin() {
return CircularIter<T>{hasComeAround ? buf + curI : buf, buf, buf + capacity, size()};
}
inline CircularIter<const T> begin() const {
return CircularIter<const T>{hasComeAround ? buf + curI : buf, buf, buf + capacity, size()};
}
inline IteratorEnd end() {
return IteratorEnd();
}
};
};
================================================
FILE: Physics3D/datastructures/compactPtrDataPair.h
================================================
#pragma once
#include <cstddef>
#include <assert.h>
/*
Stores a little extra data in the lower bits of the given ptr type.
This is usually only 3 bits, but on stronger aligned types this may be more
Pointers are aligned on 4 or 8 bytes usually, this means we can use these few bits for storing some extra small data
For example, the length of an array pointed to by the pointer if that array will always be very small.
0bPPP...PPPPP000 | 0b000...00000DDD = 0bPPP...PPPPPDDD
*/
namespace P3D {
template<typename PtrT, unsigned int BitWidth = 1, typename DataType = unsigned int>
class CompactPtrDataPair {
protected:
std::uintptr_t value;
CompactPtrDataPair(std::uintptr_t value) : value(value) {}
public:
static constexpr std::uintptr_t dataMask = (std::uintptr_t(1) << BitWidth) - std::uintptr_t(1);
static constexpr std::uintptr_t ptrMask = ~dataMask;
CompactPtrDataPair() noexcept : value(reinterpret_cast<std::uintptr_t>(nullptr)) {}
CompactPtrDataPair(PtrT* ptr, DataType data) noexcept : value(reinterpret_cast<std::uintptr_t>(ptr) | data) {
assert(reinterpret_cast<std::uintptr_t>(ptr) & dataMask == std::uintptr_t(0));
assert(data & ptrMask == std::uintptr_t(0));
}
PtrT* getPtr() const noexcept {
return reinterpret_cast<PtrT*>(value & ptrMask);
}
bool isNullptr() const noexcept {
return value & ptrMask == reinterpret_cast<std::uintptr_t>(nullptr) & ptrMask;
}
DataType getData() const noexcept {
return value & dataMask;
}
void setPtr(PtrT* ptr) noexcept {
assert(reinterpret_cast<std::uintptr_t>(ptr) & dataMask == std::uintptr_t(0));
value = reinterpret_cast<std::uintptr_t>(ptr) | (value & dataMask);
}
void setData(DataType data) noexcept {
assert(data & ptrMask == std::uintptr_t(0));
value = data | (value & ptrMask)
}
CompactPtrDataPair& operator++() {
assert(getData() < dataMask);
++value;
return *this;
}
CompactPtrDataPair& operator--() {
assert(getData() != 0);
--value;
return *this;
}
CompactPtrDataPair operator++(int) {
CompactPtrDataPair result = *this;
++(*this);
return result;
}
CompactPtrDataPair operator--(int) {
CompactPtrDataPair result = *this;
--(*this);
return result;
}
};
template<typename PtrT>
class CompactPtrDataPair<PtrT, 1, bool> {
protected:
std::uintptr_t value;
CompactPtrDataPair(std::uintptr_t value) : value(value) {}
public:
static constexpr std::uintptr_t dataMask = std::uintptr_t(1);
static constexpr std::uintptr_t ptrMask = ~dataMask;
CompactPtrDataPair() noexcept : value(reinterpret_cast<std::uintptr_t>(nullptr)) {}
CompactPtrDataPair(PtrT* ptr, bool data) noexcept : value(reinterpret_cast<std::uintptr_t>(ptr) | (data ? std::uintptr_t(1) : std::uintptr_t(0))) {
assert(reinterpret_cast<std::uintptr_t>(ptr) & dataMask == std::uintptr_t(0));
}
PtrT* getPtr() const noexcept {
return reinterpret_cast<PtrT*>(value & ptrMask);
}
bool isNullptr() const noexcept {
return value & ptrMask == reinterpret_cast<std::uintptr_t>(nullptr) & ptrMask;
}
bool getData() const noexcept {
return value & dataMask != std::uintptr_t(0);
}
void setPtr(PtrT* ptr) noexcept {
assert(reinterpret_cast<std::uintptr_t>(ptr) & dataMask == std::uintptr_t(0));
value = reinterpret_cast<std::uintptr_t>(ptr) | (value & dataMask);
}
void setData(bool data) noexcept {
if(data) {
value |= std::uintptr_t(1);
} else {
value &= ptrMask;
}
}
void setDataTrue() noexcept {
value |= std::uintptr_t(1);
}
void setDataFalse() noexcept {
value &= ptrMask;
}
void invertData() noexcept {
value ^= std::uintptr_t(1);
}
};
template<typename PtrT, unsigned int BitWidth, typename DataType>
bool operator==(CompactPtrDataPair<PtrT, BitWidth, DataType> first, CompactPtrDataPair<PtrT, BitWidth, DataType> second) {
return first.value == second.value;
}
template<typename PtrT, unsigned int BitWidth, typename DataType>
bool operator!=(CompactPtrDataPair<PtrT, BitWidth, DataType> first, CompactPtrDataPair<PtrT, BitWidth, DataType> second) {
return first.value != second.value;
}
template<typename PtrT, unsigned int BitWidth = 1, typename DataType = unsigned int>
class CompactUniquePtrDataPair : public CompactPtrDataPair<PtrT, BitWidth, DataType> {
public:
CompactUniquePtrDataPair() noexcept : CompactPtrDataPair() {}
CompactUniquePtrDataPair(PtrT* ptr, DataType data) noexcept : CompactPtrDataPair(ptr, data) {}
CompactUniquePtrDataPair(const CompactUniquePtrDataPair&) = delete;
CompactUniquePtrDataPair& operator=(const CompactUniquePtrDataPair&) = delete;
CompactUniquePtrDataPair(CompactUniquePtrDataPair&& other) noexcept : CompactPtrDataPair(other.value) {
other.value = reinterpret_cast<std::uintptr_t>(nullptr);
}
CompactUniquePtrDataPair& operator=(CompactUniquePtrDataPair&& other) noexcept {
std::uintptr_t tmpValue = this->value;
this->value = other.value;
other.value = tmpValue;
}
~CompactPtrDataPair() {
if(!this->isNullptr()) delete this->getPtr();
}
};
template<typename PtrT>
using CompactPtrBoolPair = CompactPtrDataPair<PtrT, 1, bool>;
template<typename PtrT>
using CompactUniquePtrBoolPair = CompactUniquePtrDataPair<PtrT, 1, bool>;
}
================================================
FILE: Physics3D/datastructures/iteratorEnd.h
================================================
#pragma once
namespace P3D {
struct IteratorEnd {};
};
================================================
FILE: Physics3D/datastructures/iteratorFactory.h
================================================
#pragma once
#include <utility>
#include "iteratorEnd.h"
namespace P3D {
template<typename BeginType, typename EndType = BeginType>
class IteratorFactory {
BeginType start;
EndType fin;
public:
IteratorFactory() = default;
IteratorFactory(const BeginType& start, const EndType& fin) : start(start), fin(fin) {}
IteratorFactory(BeginType&& start, EndType&& fin) : start(std::move(start)), fin(std::move(fin)) {}
BeginType begin() const { return start; }
EndType end() const { return fin; }
};
template<typename BeginType>
class IteratorFactoryWithEnd {
BeginType iter;
public:
IteratorFactoryWithEnd() = default;
IteratorFactoryWithEnd(const BeginType& iter) : iter(iter) {}
IteratorFactoryWithEnd(BeginType&& iter) : iter(std::move(iter)) {}
BeginType begin() const { return iter; }
IteratorEnd end() const { return IteratorEnd(); }
};
};
================================================
FILE: Physics3D/datastructures/monotonicTree.h
================================================
#pragma once
#include <utility>
#include <cstddef>
#include <assert.h>
#include "unmanagedArray.h"
namespace P3D {
template<typename T>
struct MonotonicTreeNode {
MonotonicTreeNode* children;
T value;
};
template<typename T>
class MonotonicTree;
/*
Warning: This is an unmanaged object, does not automatically free memory on delete
*/
template<typename T>
class MonotonicTreeBuilder {
friend class MonotonicTree<T>;
UnmanagedArray<MonotonicTreeNode<T>> allocatedMemory;
MonotonicTreeNode<T>* currentAlloc;
public:
MonotonicTreeBuilder() : allocatedMemory(), currentAlloc(nullptr) {}
MonotonicTreeBuilder(UnmanagedArray<MonotonicTreeNode<T>>&& memory) : allocatedMemory(std::move(memory)), currentAlloc(allocatedMemory.get()) {}
MonotonicTreeNode<T>* alloc(std::size_t size) {
MonotonicTreeNode<T>* claimedBlock = currentAlloc;
currentAlloc += size;
assert(currentAlloc <= allocatedMemory.getEnd());
return claimedBlock;
}
T* getPtrToFree() {
return allocatedMemory.getPtrToFree();
}
};
/*
Warning: This is an unmanaged object, does not automatically free memory on delete
*/
template<typename T>
class MonotonicTree {
UnmanagedArray<MonotonicTreeNode<T>> allocatedMemory;
public:
MonotonicTree() : allocatedMemory() {}
MonotonicTree(MonotonicTreeBuilder<T>&& builder) : allocatedMemory(std::move(builder.allocatedMemory)) {
assert(builder.currentAlloc == this->allocatedMemory.getEnd());
}
MonotonicTree& operator=(MonotonicTreeBuilder<T>&& builder) {
assert(builder.currentAlloc == builder.allocatedMemory.getEnd());
this->allocatedMemory = std::move(builder.allocatedMemory);
}
MonotonicTreeNode<T>& operator[](std::size_t index) { return allocatedMemory[index]; }
const MonotonicTreeNode<T>& operator[](std::size_t index) const { return allocatedMemory[index]; }
MonotonicTreeNode<T>* begin() { return allocatedMemory.begin(); }
const MonotonicTreeNode<T>* begin() const { return allocatedMemory.begin(); }
MonotonicTreeNode<T>* end() { return allocatedMemory.end(); }
const MonotonicTreeNode<T>* end() const { return allocatedMemory.end(); }
MonotonicTreeNode<T>* getPtrToFree() {
return allocatedMemory.getPtrToFree();
}
};
};
================================================
FILE: Physics3D/datastructures/parallelArray.h
================================================
#pragma once
#include <cstddef>
namespace P3D {
template<typename T, std::size_t C>
struct ParallelArray {
T values[C];
ParallelArray() = default;
ParallelArray(T* values) : values{} {
for(std::size_t i = 0; i < C; i++) {
this->values[i] = values[i];
}
}
ParallelArray<T, C> operator+(const ParallelArray<T, C>& other) const {
T newValues[C];
for(std::size_t i = 0; i < C; i++) {
newValues[i] = values[i] + other.values[i];
}
return ParallelArray<T, C>{newValues};
}
ParallelArray<T, C> operator-(const ParallelArray<T, C>& other) const {
T newValues[C];
for(std::size_t i = 0; i < C; i++) {
newValues[i] = values[i] - other.values[i];
}
return ParallelArray<T, C>{newValues};
}
template<typename T2>
ParallelArray<T, C> operator*(T2& other) const {
T newValues[C];
for(std::size_t i = 0; i < C; i++) {
newValues[i] = values[i] / other;
}
return ParallelArray<T, C>{newValues};
}
template<typename T2>
ParallelArray<T, C> operator/(T2& other) const {
T newValues[C];
for(std::size_t i = 0; i < C; i++) {
newValues[i] = values[i] / other;
}
return ParallelArray<T, C>{newValues};
}
void operator+=(const ParallelArray<T, C>& other) {
for(std::size_t i = 0; i < C; i++) {
values[i] += other.values[i];
}
}
void operator-=(const ParallelArray<T, C>& other) {
for(std::size_t i = 0; i < C; i++) {
values[i] -= other.values[i];
}
}
template<typename T2>
void operator*=(T2& other) {
for(std::size_t i = 0; i < C; i++) {
values[i] *= other;
}
}
template<typename T2>
void operator/=(T2& other) {
for(std::size_t i = 0; i < C; i++) {
values[i] /= other;
}
}
T& operator[](std::size_t index) {
return values[index];
}
T sum() const {
T total = values[0];
for(std::size_t i = 1; i < C; i++) {
total += values[i];
}
return total;
}
};
};
================================================
FILE: Physics3D/datastructures/sharedArray.h
================================================
#pragma once
namespace P3D {
template <typename T>
class SharedArrayPtr {
T* ptr;
size_t* refCount;
inline SharedArrayPtr(T* data, size_t* refCount)
: ptr(data)
, refCount(refCount) {}
public:
SharedArrayPtr()
: ptr(nullptr)
, refCount(nullptr) {}
explicit SharedArrayPtr(T* data)
: ptr(data)
, refCount((data == nullptr) ? nullptr : new size_t(0)) {}
SharedArrayPtr(const SharedArrayPtr<T>& other)
: ptr(other.ptr)
, refCount(other.refCount) {
if (refCount != nullptr)
++(*refCount);
}
SharedArrayPtr<T>& operator=(const SharedArrayPtr<T>& other) {
this->~SharedArrayPtr();
this->ptr = other.ptr;
this->refCount = other.refCount;
if (refCount != nullptr)
++(*refCount);
return *this;
}
SharedArrayPtr(SharedArrayPtr<T>&& other) noexcept
: ptr(other.ptr)
, refCount(other.refCount) {
other.ptr = nullptr;
other.refCount = nullptr;
}
SharedArrayPtr& operator=(SharedArrayPtr<T>&& other) noexcept {
this->~SharedArrayPtr();
this->ptr = other.ptr;
this->refCount = other.refCount;
other.ptr = nullptr;
other.refCount = nullptr;
return *this;
}
static SharedArrayPtr<T> staticSharedArrayPtr(T* data) {
return SharedArrayPtr<T>(data, nullptr);
}
~SharedArrayPtr() {
if (refCount != nullptr) {
if (*refCount == 0) {
delete refCount;
delete[] ptr;
} else {
--(*refCount);
}
}
}
T& operator*() const {
return *ptr;
}
T& operator[](size_t index) const {
return ptr[index];
}
T* operator+(size_t offset) const {
return ptr + offset;
}
T* operator-(size_t offset) const {
return ptr - offset;
}
T* operator->() const {
return ptr;
}
T* get() const {
return ptr;
}
bool operator==(T* other) const {
return ptr == other;
}
bool operator!=(T* other) const {
return ptr != other;
}
bool operator<=(T* other) const {
return ptr <= other;
}
bool operator>=(T* other) const {
return ptr >= other;
}
bool operator<(T* other) const {
return ptr < other;
}
bool operator>(T* other) const {
return ptr > other;
}
};
};
================================================
FILE: Physics3D/datastructures/smartPointers.h
================================================
#pragma once
#include <memory>
#include <atomic>
namespace P3D {
struct RC {
std::size_t refCount = 0;
virtual ~RC() {}
};
struct AtomicRC {
std::atomic<std::size_t> refCount = 0;
virtual ~AtomicRC() {}
};
template<typename T>
void intrusive_ptr_add_ref(T* iptr) noexcept {
iptr->refCount++;
}
template<typename T>
void intrusive_ptr_release(T* iptr) noexcept {
// retrieve resulting count right from the --count operator, so that std::atomic is properly used if iptr->refCount is atomic.
auto resultingCount = --iptr->refCount;
if (resultingCount == 0)
delete iptr;
}
/*
Defines a managed pointer to a shared object, of which unlike shared_ptr, the refCount is stored in the object itself.
Requires the managed object to define a public (optionally atomic) integer-like field called 'refCount'.
*/
template<typename T>
class intrusive_ptr {
protected:
template<typename U> friend class intrusive_ptr;
T* ptr;
public:
intrusive_ptr() noexcept : ptr(nullptr) {}
explicit intrusive_ptr(T* ptr, bool addRef = true) noexcept : ptr(ptr) {
if (ptr && addRef)
intrusive_ptr_add_ref(ptr);
}
intrusive_ptr(const intrusive_ptr& iptr) noexcept : ptr(iptr.ptr) {
if (ptr)
intrusive_ptr_add_ref(ptr);
}
intrusive_ptr(intrusive_ptr&& iptr) noexcept : ptr(iptr.ptr) {
iptr.ptr = nullptr;
}
~intrusive_ptr() noexcept {
if (ptr)
intrusive_ptr_release(ptr);
}
intrusive_ptr& operator=(const intrusive_ptr& iptr) noexcept {
return operator=(iptr.ptr);
}
intrusive_ptr& operator=(intrusive_ptr&& iptr) noexcept {
swap(iptr);
return *this;
}
template<typename U>
intrusive_ptr& operator=(const intrusive_ptr<U>& iptr) noexcept {
return operator=(iptr.ptr);
}
intrusive_ptr& operator=(T* ptr) noexcept {
if (ptr != this->ptr) {
const T* tmp = this->ptr;
if (ptr)
intrusive_ptr_add_ref(ptr);
this->ptr = ptr;
if (tmp)
intrusive_ptr_release(tmp);
}
return *this;
}
[[nodiscard]] T& operator*() const noexcept {
return *ptr;
}
[[nodiscard]] T* get() const noexcept {
return ptr;
}
[[nodiscard]] T* operator->() const noexcept {
return ptr;
}
[[nodiscard]] bool valid() const noexcept {
return ptr != nullptr;
}
[[nodiscard]] bool invalid() const noexcept {
return ptr == nullptr;
}
void reset() noexcept {
T* const tmp = ptr;
ptr = nullptr;
if (tmp)
intrusive_ptr_release(tmp);
}
void swap(intrusive_ptr& iptr) noexcept {
T* const tmp = ptr;
ptr = iptr.ptr;
iptr.ptr = tmp;
}
void attach(T* ptr) noexcept {
T* const tmp = this->ptr;
this->ptr = ptr;
if (tmp)
intrusive_ptr_release(tmp);
}
[[nodiscard]] T* detach() noexcept {
T* const tmp = ptr;
ptr = nullptr;
return tmp;
}
[[nodiscard]] operator bool() const noexcept {
return ptr != nullptr;
}
[[nodiscard]] bool operator!() const noexcept {
return ptr == nullptr;
}
};
template <typename T, typename U>
bool operator==(const intrusive_ptr<T>& iptr1, const intrusive_ptr<U>& iptr2) noexcept {
return (iptr1.get() == iptr2.get());
}
template <typename T, typename U>
bool operator!=(const intrusive_ptr<T>& iptr1, const intrusive_ptr<U>& iptr2) noexcept {
return (iptr1.get() != iptr2.get());
}
template <typename T>
bool operator==(const intrusive_ptr<T>& iptr, T* ptr) noexcept {
return (iptr.get() == ptr);
}
template <typename T>
bool operator!=(const intrusive_ptr<T>& iptr, T* ptr) noexcept {
return (iptr.get() != ptr);
}
template <typename T>
bool operator==(T* ptr, const intrusive_ptr<T>& iptr) noexcept {
return (ptr == iptr.get());
}
template <typename T>
bool operator!=(T* ptr, const intrusive_ptr<T>& iptr) noexcept {
return (ptr != iptr.get());
}
template <typename T>
bool operator==(std::nullptr_t nptr, const intrusive_ptr<T>& iptr) noexcept {
return (nullptr == iptr.get());
}
template <typename T>
bool operator!=(std::nullptr_t nptr, const intrusive_ptr<T>& iptr) noexcept {
return (nullptr != iptr.get());
}
template <typename T>
bool operator==(const intrusive_ptr<T>& iptr, std::nullptr_t nptr) noexcept {
return (iptr.get() == nullptr);
}
template <typename T>
bool operator!=(const intrusive_ptr<T>& iptr, std::nullptr_t nptr) noexcept {
return (iptr.get() != nullptr);
}
template<typename T, typename... Args>
intrusive_ptr<T> make_intrusive(Args&&... args) noexcept {
return intrusive_ptr<T>(new T(std::forward<Args>(args)...));
}
template <class T, class U>
intrusive_ptr<T> intrusive_cast(const intrusive_ptr<U>& iptr) noexcept {
return intrusive_ptr<T>(static_cast<T*>(iptr.get()));
}
template<typename T>
using IRef = intrusive_ptr<T>;
template<typename T>
using SRef = std::shared_ptr<T>;
template<typename T>
using URef = std::unique_ptr<T>;
}
================================================
FILE: Physics3D/datastructures/uniqueArrayPtr.h
================================================
#include <cstddef>
#include <utility>
#include <assert.h>
namespace P3D {
template<typename T>
struct DefaultArrayDelete {
void operator()(T* arr) const {
delete[] arr;
}
};
struct DoNothingDelete {
void operator()(void* arr) const noexcept {}
};
template<typename T, typename Deleter = DefaultArrayDelete<T>>
class UniqueArrayPtr {
T* ptr;
T* endPtr;
Deleter deleter;
public:
// ignore endPtr, endPtr is only valid if ptr is not nullptr
UniqueArrayPtr() : ptr(nullptr) {}
UniqueArrayPtr(T* ptr, std::size_t size, Deleter deleter = {}) : ptr(ptr), endPtr(ptr + size), deleter(deleter) {}
~UniqueArrayPtr() {
deleter(this->ptr);
}
UniqueArrayPtr(const UniqueArrayPtr&) = delete;
UniqueArrayPtr& operator=(const UniqueArrayPtr&) = delete;
UniqueArrayPtr(UniqueArrayPtr&& other) noexcept : ptr(other.ptr), endPtr(other.endPtr), deleter(std::move(other.deleter)) {
other.ptr = nullptr;
}
UniqueArrayPtr& operator=(UniqueArrayPtr&& other) noexcept {
std::swap(this->ptr, other.ptr);
std::swap(this->endPtr, other.endPtr);
std::swap(this->deleter, other.deleter);
return *this;
}
T& operator[](std::size_t index) {
assert(ptr != nullptr);
assert(index >= 0 && ptr + index < endPtr);
return ptr[index];
}
const T& operator[](std::size_t index) const {
assert(ptr != nullptr);
assert(index >= 0 && ptr + index < endPtr);
return ptr[index];
}
T& operator*() { assert(ptr != nullptr); return *ptr; }
const T& operator*() const { assert(ptr != nullptr); return *ptr; }
T* begin() { assert(ptr != nullptr); return ptr; }
const T* begin() const { assert(ptr != nullptr); return ptr; }
T* end() { assert(ptr != nullptr); return endPtr; }
const T* end() const { assert(ptr != nullptr); return endPtr; }
T* get() { return ptr; }
const T* get() const { return ptr; }
T* getEnd() { assert(ptr != nullptr); return endPtr; }
const T* getEnd() const { assert(ptr != nullptr); return endPtr; }
};
};
================================================
FILE: Physics3D/datastructures/unmanagedArray.h
================================================
#include <cstddef>
#include <utility>
#include <assert.h>
/*
Warning: This is an unmanaged object, does not automatically free memory on delete
*/
namespace P3D {
template<typename T>
class UnmanagedArray {
T* ptr;
T* endPtr;
public:
// ignore endPtr, endPtr is only valid if ptr is not nullptr
UnmanagedArray() : ptr(nullptr) {}
UnmanagedArray(T* ptr, std::size_t size) : ptr(ptr), endPtr(ptr + size) {}
T& operator[](std::size_t index) {
assert(ptr != nullptr);
assert(index >= 0 && ptr + index < endPtr);
return ptr[index];
}
const T& operator[](std::size_t index) const {
assert(ptr != nullptr);
assert(index >= 0 && ptr + index < endPtr);
return ptr[index];
}
T& operator*() { assert(ptr != nullptr); return *ptr; }
const T& operator*() const { assert(ptr != nullptr); return *ptr; }
T* begin() { assert(ptr != nullptr); return ptr; }
const T* begin() const { assert(ptr != nullptr); return ptr; }
T* end() { assert(ptr != nullptr); return endPtr; }
const T* end() const { assert(ptr != nullptr); return endPtr; }
T* get() { return ptr; }
const T* get() const { return ptr; }
T* getEnd() { assert(ptr != nullptr); return endPtr; }
const T* getEnd() const { assert(ptr != nullptr); return endPtr; }
T* getPtrToFree() {
return ptr;
}
};
};
================================================
FILE: Physics3D/datastructures/unorderedVector.h
================================================
#pragma once
#include <vector>
#include <assert.h>
namespace P3D {
template<typename T>
class UnorderedVector : public std::vector<T> {
public:
inline void remove(T&& element) {
T* el = &element;
assert(el >= &std::vector<T>::front());
T* bck = &std::vector<T>::back();
assert(el <= bck);
if(el != bck) {
*el = std::move(*bck);
}
std::vector<T>::pop_back();
}
};
};
================================================
FILE: Physics3D/externalforces/directionalGravity.cpp
================================================
#include "directionalGravity.h"
#include "../math/position.h"
#include "../part.h"
#include "../physical.h"
#include "../world.h"
namespace P3D {
void DirectionalGravity::apply(WorldPrototype* world) {
for(MotorizedPhysical* p : world->physicals) {
p->applyForceAtCenterOfMass(gravity * p->totalMass);
}
}
double DirectionalGravity::getPotentialEnergyForObject(const WorldPrototype* world, const Part& part) const {
return Vec3(Position() - part.getCenterOfMass()) * gravity * part.getMass();
}
double DirectionalGravity::getPotentialEnergyForObject(const WorldPrototype* world, const MotorizedPhysical& phys) const {
return Vec3(Position() - phys.getCenterOfMass()) * gravity * phys.totalMass;
}
};
================================================
FILE: Physics3D/externalforces/directionalGravity.h
================================================
#pragma once
#include "../math/linalg/vec.h"
#include "externalForce.h"
namespace P3D {
class WorldPrototype;
class Part;
class MotorizedPhysical;
class DirectionalGravity : public ExternalForce {
public:
Vec3 gravity;
DirectionalGravity(Vec3 gravity) : gravity(gravity) {}
virtual void apply(WorldPrototype* world) override;
virtual double getPotentialEnergyForObject(const WorldPrototype* world, const Part& part) const override;
virtual double getPotentialEnergyForObject(const WorldPrototype* world, const MotorizedPhysical& phys) const override;
};
};
================================================
FILE: Physics3D/externalforces/externalForce.cpp
================================================
#include "externalForce.h"
#include "../world.h"
#include "../part.h"
#include "../physical.h"
namespace P3D {
double ExternalForce::getPotentialEnergyForObject(const WorldPrototype* world, const Part& part) const {
return 0.0;
}
double ExternalForce::getPotentialEnergyForObject(const WorldPrototype* world, const MotorizedPhysical& phys) const {
double total = 0.0;
for(const Part& p : phys.rigidBody) {
total += this->getPotentialEnergyForObject(world, p);
}
return total;
}
double ExternalForce::getTotalPotentialEnergyForThisForce(const WorldPrototype* world) const {
double total = 0.0;
for(MotorizedPhysical* p : world->physicals) {
total += this->getPotentialEnergyForObject(world, *p);
}
return total;
}
};
================================================
FILE: Physics3D/externalforces/externalForce.h
================================================
#pragma once
namespace P3D {
class WorldPrototype;
class Part;
class MotorizedPhysical;
class ExternalForce {
public:
virtual void apply(WorldPrototype* world) = 0;
// These do not necessarity have to be implemented. Used for world potential energy computation
virtual double getPotentialEnergyForObject(const WorldPrototype* world, const Part& part) const;
// default implementation sums potential energies of constituent parts
virtual double getPotentialEnergyForObject(const WorldPrototype* world, const MotorizedPhysical& phys) const;
virtual double getTotalPotentialEnergyForThisForce(const WorldPrototype* world) const;
};
};
================================================
FILE: Physics3D/externalforces/magnetForce.cpp
================================================
#include "magnetForce.h"
#include "../world.h"
namespace P3D {
MagnetForce::MagnetForce(double pickerStrength, double pickerSpeedStrength) :
selectedPart(nullptr),
localSelectedPoint(),
magnetPoint(),
pickerStrength(pickerStrength),
pickerSpeedStrength(pickerSpeedStrength) {}
MagnetForce::MagnetForce(Part& selectedPart, Vec3 localSelectedPoint, Position magnetPoint, double pickerStrength, double pickerSpeedStrength) :
selectedPart(&selectedPart),
localSelectedPoint(localSelectedPoint),
magnetPoint(magnetPoint),
pickerStrength(pickerStrength),
pickerSpeedStrength(pickerSpeedStrength) {}
void MagnetForce::apply(WorldPrototype* world) {
if(selectedPart != nullptr) {
Physical* selectedPartPhys = selectedPart->getPhysical();
if(selectedPartPhys != nullptr) {
MotorizedPhysical* selectedPhysical = selectedPartPhys->mainPhysical;
// Magnet force
Position absoluteSelectedPoint = selectedPart->getCFrame().localToGlobal(localSelectedPoint);
Position centerOfmass = selectedPhysical->getCenterOfMass();
Vec3 delta = magnetPoint - absoluteSelectedPoint;
Vec3 relativeSelectedPointSpeed = selectedPart->getMotion().getVelocityOfPoint(absoluteSelectedPoint - centerOfmass);
Vec3 force = selectedPhysical->totalMass * (delta * pickerStrength - relativeSelectedPointSpeed * pickerSpeedStrength);
selectedPhysical->applyForceToPhysical(absoluteSelectedPoint - centerOfmass, force);
selectedPhysical->motionOfCenterOfMass.rotation.rotation[0] *= 0.8;
}
}
}
};
================================================
FILE: Physics3D/externalforces/magnetForce.h
================================================
#pragma once
#include "externalForce.h"
#include "../part.h"
#include "../math/linalg/vec.h"
#include "../math/position.h"
namespace P3D {
class MagnetForce : public ExternalForce {
public:
Part* selectedPart;
Vec3 localSelectedPoint;
Position magnetPoint;
double pickerStrength;
double pickerSpeedStrength;
MagnetForce() = default;
MagnetForce(double pickerStrength, double pickerSpeedStrength);
MagnetForce(Part& selectedPart, Vec3 localSelectedPoint, Position magnetPoint, double pickerStrength, double pickerSpeedStrength);
virtual void apply(WorldPrototype* world) override;
};
};
================================================
FILE: Physics3D/geometry/builtinShapeClasses.cpp
================================================
#include "builtinShapeClasses.h"
#include "shapeCreation.h"
#include "shapeLibrary.h"
#include "../math/constants.h"
namespace P3D {
#pragma region CubeClass
CubeClass::CubeClass() : ShapeClass(8, Vec3(0, 0, 0), ScalableInertialMatrix(Vec3(8.0 / 3.0, 8.0 / 3.0, 8.0 / 3.0), Vec3(0, 0, 0)), CUBE_CLASS_ID) {
// CubeClass is a singleton instance, starting refCount >= 1 ensures it is never deleted
this->refCount = 1;
}
bool CubeClass::containsPoint(Vec3 point) const {
return std::abs(point.x) <= 1.0 && std::abs(point.y) <= 1.0 && std::abs(point.z) <= 1.0;
}
double CubeClass::getIntersectionDistance(Vec3 origin, Vec3 direction) const {
if(origin.x < 0) {
origin.x = -origin.x;
direction.x = -direction.x;
}
if(origin.y < 0) {
origin.y = -origin.y;
direction.y = -direction.y;
}
if(origin.z < 0) {
origin.z = -origin.z;
direction.z = -direction.z;
}
//origin + t * direction = x1z
double tx = (1 - origin.x) / direction.x;
Vec3 intersX = origin + tx * direction;
if(std::abs(intersX.y) <= 1.0 && std::abs(intersX.z) <= 1.0) return tx;
double ty = (1 - origin.y) / direction.y;
Vec3 intersY = origin + ty * direction;
if(std::abs(intersY.x) <= 1.0 && std::abs(intersY.z) <= 1.0) return ty;
double tz = (1 - origin.z) / direction.z;
Vec3 intersZ = origin + tz * direction;
if(std::abs(intersZ.x) <= 1.0 && std::abs(intersZ.y) <= 1.0) return tz;
return std::numeric_limits<double>::infinity();
}
BoundingBox CubeClass::getBounds(const Rotation& rotation, const DiagonalMat3& scale) const {
Mat3 referenceFrame = rotation.asRotationMatrix() * scale;
double x = std::abs(referenceFrame(0, 0)) + std::abs(referenceFrame(0, 1)) + std::abs(referenceFrame(0, 2));
double y = std::abs(referenceFrame(1, 0)) + std::abs(referenceFrame(1, 1)) + std::abs(referenceFrame(1, 2));
double z = std::abs(referenceFrame(2, 0)) + std::abs(referenceFrame(2, 1)) + std::abs(referenceFrame(2, 2));
BoundingBox result{-x,-y,-z,x,y,z};
return result;
}
double CubeClass::getScaledMaxRadiusSq(DiagonalMat3 scale) const {
return scale[0] * scale[0] + scale[1] * scale[1] + scale[2] * scale[2];
}
Vec3f CubeClass::furthestInDirection(const Vec3f& direction) const {
return Vec3f(direction.x < 0 ? -1.0f : 1.0f, direction.y < 0 ? -1.0f : 1.0f, direction.z < 0 ? -1.0f : 1.0f);
}
Polyhedron CubeClass::asPolyhedron() const {
return ShapeLibrary::createCube(2.0);
}
#pragma endregion
#pragma region SphereClass
SphereClass::SphereClass() : ShapeClass(4.0 / 3.0 * PI, Vec3(0, 0, 0), ScalableInertialMatrix(Vec3(4.0 / 15.0 * PI, 4.0 / 15.0 * PI, 4.0 / 15.0 * PI), Vec3(0, 0, 0)), SPHERE_CLASS_ID) {
// SphereClass is a singleton instance, starting refCount >= 1 ensures it is never deleted
this->refCount = 1;
}
bool SphereClass::containsPoint(Vec3 point) const {
return lengthSquared(point) <= 1.0;
}
double SphereClass::getIntersectionDistance(Vec3 origin, Vec3 direction) const {
//o*o + o*d*t + o*d*t + t*t*d*d
double c = origin * origin - 1;
double b = origin * direction;
double a = direction * direction;
// solve a*t^2 + 2*b*t + c
double D = b * b - a * c;
if(D >= 0) {
return (-b + -sqrt(D)) / a;
} else {
return std::numeric_limits<double>::infinity();
}
}
BoundingBox SphereClass::getBounds(const Rotation& rotation, const DiagonalMat3& scale) const {
double s = scale[0];
return BoundingBox{-s, -s, -s, s, s, s};
}
double SphereClass::getScaledMaxRadiusSq(DiagonalMat3 scale) const {
return scale[0] * scale[0];
}
double SphereClass::getScaledMaxRadius(DiagonalMat3 scale) const {
return scale[0];
}
Vec3f SphereClass::furthestInDirection(const Vec3f& direction) const {
float lenSq = lengthSquared(direction);
if(lenSq == 0.0f) return Vec3f(1.0f, 0.0f, 0.0f);
return direction / std::sqrt(lenSq);
}
Polyhedron SphereClass::asPolyhedron() const {
return ShapeLibrary::createSphere(1.0, 3);
}
void SphereClass::setScaleX(double newX, DiagonalMat3& scale) const {
scale[0] = newX;
scale[1] = newX;
scale[2] = newX;
}
void SphereClass::setScaleY(double newY, DiagonalMat3& scale) const {
scale[0] = newY;
scale[1] = newY;
scale[2] = newY;
}
void SphereClass::setScaleZ(double newZ, DiagonalMat3& scale) const {
scale[0] = newZ;
scale[1] = newZ;
scale[2] = newZ;
}
#pragma endregion
#pragma region CylinderClass
/*
Inertia of cyllinder:
z = V * 1/2
x, y = V * 7/12
X = y + z = 7/12
Y = x + z = 7/12
Z = x + y = 1/2
x = 1/4 * PI * 2
y = 1/4 * PI * 2
z = 1/3 * PI * 2
*/
CylinderClass::CylinderClass() : ShapeClass(PI * 2.0, Vec3(0, 0, 0), ScalableInertialMatrix(Vec3(PI / 2.0, PI / 2.0, PI * 2.0 / 3.0), Vec3(0, 0, 0)), CYLINDER_CLASS_ID) {
// CylinderClass is a singleton instance, starting refCount >= 1 ensures it is never deleted
this->refCount = 1;
}
bool CylinderClass::containsPoint(Vec3 point) const {
return std::abs(point.z) <= 1.0 && point.x * point.x + point.y + point.y <= 1.0;
}
double CylinderClass::getIntersectionDistance(Vec3 origin, Vec3 direction) const {
Vec2 xyOrigin(origin.x, origin.y);
Vec2 xyDirection(direction.x, direction.y);
//o*o + o*d*t + o*d*t + t*t*d*d
double c = xyOrigin * xyOrigin - 1;
double b = xyOrigin * xyDirection;
double a = xyDirection * xyDirection;
// solve a*t^2 + 2*b*t + c
double D = b * b - a * c;
if(D >= 0) {
double t = (-b + -sqrt(D)) / a;
double z = origin.z + t * direction.z;
if(std::abs(z) <= 1.0) {
return t;
} else {
// origin + t * direction = 1 => t = (1-origin)/direction
double t2 = (((origin.z >= 0) ? 1 : -1) - origin.z) / direction.z;
double x = origin.x + t2 * direction.x;
double y = origin.y + t2 * direction.y;
if(x * x + y * y <= 1.0) {
return t2;
} else {
return std::numeric_limits<double>::infinity();
}
}
} else {
return std::numeric_limits<double>::infinity();
}
}
BoundingBox CylinderClass::getBounds(const Rotation& rotation, const DiagonalMat3& scale) const {
double height = scale[2];
double radius = scale[0];
Vec3 normalizedZVector = rotation.getZ();
Vec3 zVector = normalizedZVector * height;
double extraX = std::hypot(normalizedZVector.y, normalizedZVector.z);
double extraY = std::hypot(normalizedZVector.x, normalizedZVector.z);
double extraZ = std::hypot(normalizedZVector.x, normalizedZVector.y);
double x = std::abs(zVector.x) + extraX * radius;
double y = std::abs(zVector.y) + extraY * radius;
double z = std::abs(zVector.z) + extraZ * radius;
return BoundingBox{-x, -y, -z, x, y, z};
}
double CylinderClass::getScaledMaxRadiusSq(DiagonalMat3 scale) const {
return scale[0] * scale[0] + scale[2] * scale[2];
}
Vec3f CylinderClass::furthestInDirection(const Vec3f& direction) const {
float z = (direction.z >= 0.0f) ? 1.0f : -1.0f;
float lenSq = direction.x * direction.x + direction.y * direction.y;
if(lenSq == 0.0) return Vec3f(1.0f, 0.0f, z);
float length = sqrt(lenSq);
return Vec3f(direction.x / length, direction.y / length, z);
}
Polyhedron CylinderClass::asPolyhedron() const {
return ShapeLibrary::createPrism(64, 1.0, 2.0);
}
void CylinderClass::setScaleX(double newX, DiagonalMat3& scale) const {
scale[0] = newX;
scale[1] = newX;
}
void CylinderClass::setScaleY(double newY, DiagonalMat3& scale) const {
scale[0] = newY;
scale[1] = newY;
}
#pragma endregion
#pragma region WedgeClass
WedgeClass::WedgeClass() : ShapeClass(4.0, Vec3(-1 / 3, 0, 1 / 3), ScalableInertialMatrix(Vec3(0.9030, 0.6032, 0.8411), Vec3(0.3517, 0.0210, 0.1667)), WEDGE_CLASS_ID) {
// WedgeClass is a singleton instance, starting refCount >= 1 ensures it is never deleted
this->refCount = 1;
}
bool WedgeClass::containsPoint(Vec3 point) const {
return std::abs(point.x) <= 1.0 && std::abs(point.y) <= 1.0 && std::abs(point.z) <= 1.0 && point.x + point.y <= 0.0;
}
double WedgeClass::getIntersectionDistance(Vec3 origin, Vec3 direction) const {
double currMin = std::numeric_limits<double>::max();
double ty = (-1 - origin.y) / direction.y;
Vec3 intersY = origin + ty * direction;
if(std::abs(intersY.x) <= 1.0 && std::abs(intersY.z) <= 1.0 && intersY.x <= 1.0 && ty > 0) {
if(ty < currMin) {
currMin = ty;
}
}
double tx = (-1 - origin.x) / direction.x;
Vec3 intersX = origin + tx * direction;
if(std::abs(intersX.y) <= 1.0 && std::abs(intersX.z) <= 1.0 && intersX.y <= 1.0 && tx > 0) {
if(tx < currMin) {
currMin = tx;
}
}
{
double tz = (-1 - origin.z) / direction.z;
Vec3 intersZ = origin + tz * direction;
if(std::abs(intersZ.x) <= 1.0 && std::abs(intersZ.y) <= 1.0 && intersZ.x + intersZ.y <= 0.0 && tz > 0) {
if(tz < currMin) {
currMin = tz;
}
}
}
{
double tz = (1 - origin.z) / direction.z;
Vec3 intersZ = origin + tz * direction;
if(std::abs(intersZ.x) <= 1.0 && std::abs(intersZ.y) <= 1.0 && intersZ.x + intersZ.y <= 0.0 && tz > 0) {
if(tz < currMin) {
currMin = tz;
}
}
}
const double dn = direction.x + direction.y;
double t = (-origin.x - origin.y) / dn;
Vec3 point = origin + t * direction;
if(std::abs(point.x) <= 1.0 && std::abs(point.y) <= 1.0 && std::abs(point.z) <= 1.0 && t > 0) {
if(t < currMin) {
currMin = t;
}
}
return currMin;
}
BoundingBox WedgeClass::getBounds(const Rotation& rotation, const DiagonalMat3& scale) const {
const Mat3& rotMat = rotation.asRotationMatrix();
Vec3 scaleRot[3] = {};
for(int i = 0; i < 3; i++) {
scaleRot[i] = scale[i] * rotMat.getCol(i);
}
const Vec3 vertices[] = {
-scaleRot[0] - scaleRot[1] - scaleRot[2],
-scaleRot[0] - scaleRot[1] + scaleRot[2],
scaleRot[0] - scaleRot[1] + scaleRot[2],
scaleRot[0] - scaleRot[1] - scaleRot[2],
-scaleRot[0] + scaleRot[1] - scaleRot[2],
-scaleRot[0] + scaleRot[1] + scaleRot[2],
};
double xmin = vertices[0].x; double xmax = vertices[0].x;
double ymin = vertices[0].y; double ymax = vertices[0].y;
double zmin = vertices[0].z; double zmax = vertices[0].z;
for(int i = 1; i < ShapeLibrary::wedgeVertexCount; i++) {
const Vec3& current = vertices[i];
if(current.x < xmin) xmin = current.x;
if(current.x > xmax) xmax = current.x;
if(current.y < ymin) ymin = current.y;
if(current.y > ymax) ymax = current.y;
if(current.z < zmin) zmin = current.z;
if(current.z > zmax) zmax = current.z;
}
return BoundingBox{xmin, ymin, zmin, xmax, ymax, zmax};
}
double WedgeClass::getScaledMaxRadiusSq(DiagonalMat3 scale) const {
return scale[0] * scale[0] + scale[1] * scale[1] + scale[2] * scale[2];
}
Vec3f WedgeClass::furthestInDirection(const Vec3f& direction) const {
float best = ShapeLibrary::wedgeVertices[0] * direction;
Vec3f bestVertex = ShapeLibrary::wedgeVertices[0];
for(int i = 1; i < ShapeLibrary::wedgeVertexCount; i++) {
float current = ShapeLibrary::wedgeVertices[i] * direction;
if(current > best) {
best = current;
bestVertex = ShapeLibrary::wedgeVertices[i];
}
}
return bestVertex;
}
Polyhedron WedgeClass::asPolyhedron() const {
return ShapeLibrary::wedge;
}
#pragma endregion
#pragma region CornerClass
CornerClass::CornerClass() : ShapeClass(4 / 3, Vec3(-2 / 3, -2 / 3, -2 / 3), ScalableInertialMatrix(Vec3(0.2000, 0.2000, 0.2000), Vec3(0.0667, 0.0667, 0.0667)), CORNER_CLASS_ID) {
// CornerClass is a singleton instance, starting refCount >= 1 ensures it is never deleted
this->refCount = 1;
}
bool CornerClass::containsPoint(Vec3 point) const {
return point.x >= -1.0 && po
gitextract_pl6iqfhu/ ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.md │ │ └── feature_request.md │ └── workflows/ │ ├── msvcBuild.yml │ └── ubuntuBuild.yml ├── .gitignore ├── CMakeLists.txt ├── LICENSE.md ├── Physics3D/ │ ├── CMakeLists.txt │ ├── Physics3D.vcxproj │ ├── boundstree/ │ │ ├── boundsTree.cpp │ │ ├── boundsTree.h │ │ ├── boundsTreeAVX.cpp │ │ ├── boundsTreeSSE.cpp │ │ └── filters/ │ │ ├── outOfBoundsFilter.h │ │ ├── rayIntersectsBoundsFilter.h │ │ ├── visibilityFilter.cpp │ │ └── visibilityFilter.h │ ├── colissionBuffer.h │ ├── constraints/ │ │ ├── ballConstraint.cpp │ │ ├── ballConstraint.h │ │ ├── barConstraint.cpp │ │ ├── barConstraint.h │ │ ├── constraint.cpp │ │ ├── constraint.h │ │ ├── constraintGroup.cpp │ │ ├── constraintGroup.h │ │ ├── constraintImpl.h │ │ ├── hingeConstraint.cpp │ │ └── hingeConstraint.h │ ├── datastructures/ │ │ ├── alignedPtr.h │ │ ├── aligned_alloc.cpp │ │ ├── aligned_alloc.h │ │ ├── buffers.h │ │ ├── compactPtrDataPair.h │ │ ├── iteratorEnd.h │ │ ├── iteratorFactory.h │ │ ├── monotonicTree.h │ │ ├── parallelArray.h │ │ ├── sharedArray.h │ │ ├── smartPointers.h │ │ ├── uniqueArrayPtr.h │ │ ├── unmanagedArray.h │ │ └── unorderedVector.h │ ├── externalforces/ │ │ ├── directionalGravity.cpp │ │ ├── directionalGravity.h │ │ ├── externalForce.cpp │ │ ├── externalForce.h │ │ ├── magnetForce.cpp │ │ └── magnetForce.h │ ├── geometry/ │ │ ├── builtinShapeClasses.cpp │ │ ├── builtinShapeClasses.h │ │ ├── computationBuffer.cpp │ │ ├── computationBuffer.h │ │ ├── convexShapeBuilder.cpp │ │ ├── convexShapeBuilder.h │ │ ├── genericCollidable.h │ │ ├── genericIntersection.cpp │ │ ├── genericIntersection.h │ │ ├── indexedShape.cpp │ │ ├── indexedShape.h │ │ ├── intersection.cpp │ │ ├── intersection.h │ │ ├── polyhedron.cpp │ │ ├── polyhedron.h │ │ ├── scalableInertialMatrix.h │ │ ├── shape.cpp │ │ ├── shape.h │ │ ├── shapeBuilder.cpp │ │ ├── shapeBuilder.h │ │ ├── shapeClass.cpp │ │ ├── shapeClass.h │ │ ├── shapeCreation.cpp │ │ ├── shapeCreation.h │ │ ├── shapeLibrary.cpp │ │ ├── shapeLibrary.h │ │ ├── triangleMesh.cpp │ │ ├── triangleMesh.h │ │ ├── triangleMeshAVX.cpp │ │ ├── triangleMeshCommon.h │ │ ├── triangleMeshSSE.cpp │ │ └── triangleMeshSSE4.cpp │ ├── hardconstraints/ │ │ ├── constraintTemplates.h │ │ ├── controller/ │ │ │ ├── constController.h │ │ │ ├── sineWaveController.cpp │ │ │ └── sineWaveController.h │ │ ├── fixedConstraint.cpp │ │ ├── fixedConstraint.h │ │ ├── hardConstraint.cpp │ │ ├── hardConstraint.h │ │ ├── hardPhysicalConnection.cpp │ │ ├── hardPhysicalConnection.h │ │ ├── motorConstraint.cpp │ │ ├── motorConstraint.h │ │ └── sinusoidalPistonConstraint.h │ ├── inertia.cpp │ ├── inertia.h │ ├── layer.cpp │ ├── layer.h │ ├── math/ │ │ ├── boundingBox.h │ │ ├── bounds.h │ │ ├── cframe.h │ │ ├── constants.h │ │ ├── fix.h │ │ ├── globalCFrame.h │ │ ├── globalTransform.h │ │ ├── linalg/ │ │ │ ├── commonMatrices.h │ │ │ ├── eigen.cpp │ │ │ ├── eigen.h │ │ │ ├── largeMatrix.h │ │ │ ├── largeMatrixAlgorithms.h │ │ │ ├── mat.h │ │ │ ├── quat.h │ │ │ ├── trigonometry.cpp │ │ │ ├── trigonometry.h │ │ │ └── vec.h │ │ ├── mathUtil.h │ │ ├── position.h │ │ ├── predefinedTaylorExpansions.h │ │ ├── ray.h │ │ ├── rotation.h │ │ ├── taylorExpansion.h │ │ ├── transform.h │ │ └── utils.h │ ├── misc/ │ │ ├── catchable_assert.h │ │ ├── cpuid.cpp │ │ ├── cpuid.h │ │ ├── debug.cpp │ │ ├── debug.h │ │ ├── physicsProfiler.cpp │ │ ├── physicsProfiler.h │ │ ├── profiling.h │ │ ├── serialization/ │ │ │ ├── dynamicSerialize.h │ │ │ ├── serialization.cpp │ │ │ ├── serialization.h │ │ │ ├── serializeBasicTypes.cpp │ │ │ ├── serializeBasicTypes.h │ │ │ └── sharedObjectSerializer.h │ │ ├── toString.h │ │ ├── unreachable.h │ │ ├── validityHelper.cpp │ │ └── validityHelper.h │ ├── motion.h │ ├── part.cpp │ ├── part.h │ ├── physical.cpp │ ├── physical.h │ ├── relativeMotion.h │ ├── rigidBody.cpp │ ├── rigidBody.h │ ├── softlinks/ │ │ ├── alignmentLink.cpp │ │ ├── alignmentLink.h │ │ ├── elasticLink.cpp │ │ ├── elasticLink.h │ │ ├── magneticLink.cpp │ │ ├── magneticLink.h │ │ ├── softLink.cpp │ │ ├── softLink.h │ │ ├── springLink.cpp │ │ └── springLink.h │ ├── threading/ │ │ ├── physicsThread.cpp │ │ ├── physicsThread.h │ │ ├── sharedLockGuard.h │ │ ├── threadPool.h │ │ ├── upgradeableMutex.cpp │ │ └── upgradeableMutex.h │ ├── world.cpp │ ├── world.h │ ├── worldIteration.h │ ├── worldPhysics.cpp │ └── worldPhysics.h ├── Physics3D.sln ├── README.md ├── _config.yml ├── application/ │ ├── application.cpp │ ├── application.h │ ├── application.rc │ ├── application.vcxproj │ ├── builtinWorlds.cpp │ ├── builtinWorlds.h │ ├── core.cpp │ ├── core.h │ ├── debugData.natvis │ ├── ecs/ │ │ ├── components.h │ │ └── entityBuilder.h │ ├── eventHandler.cpp │ ├── eventHandler.h │ ├── extendedPart.cpp │ ├── extendedPart.h │ ├── input/ │ │ ├── playerController.cpp │ │ ├── playerController.h │ │ ├── standardInputHandler.cpp │ │ └── standardInputHandler.h │ ├── io/ │ │ ├── saveDialog.cpp │ │ ├── saveDialog.h │ │ ├── serialization.cpp │ │ └── serialization.h │ ├── layer/ │ │ ├── cameraLayer.cpp │ │ ├── cameraLayer.h │ │ ├── constraintLayer.cpp │ │ ├── constraintLayer.h │ │ ├── debugLayer.cpp │ │ ├── debugLayer.h │ │ ├── debugOverlay.cpp │ │ ├── debugOverlay.h │ │ ├── guiLayer.cpp │ │ ├── guiLayer.h │ │ ├── imguiLayer.cpp │ │ ├── imguiLayer.h │ │ ├── modelLayer.cpp │ │ ├── modelLayer.h │ │ ├── pickerLayer.cpp │ │ ├── pickerLayer.h │ │ ├── postprocessLayer.cpp │ │ ├── postprocessLayer.h │ │ ├── shadowLayer.cpp │ │ ├── shadowLayer.h │ │ ├── skyboxLayer.cpp │ │ ├── skyboxLayer.h │ │ ├── testLayer.cpp │ │ └── testLayer.h │ ├── legacy/ │ │ └── frames.h │ ├── math.natvis │ ├── picker/ │ │ ├── ray.cpp │ │ ├── ray.h │ │ ├── selection.cpp │ │ ├── selection.h │ │ └── tools/ │ │ ├── alignmentLinkTool.cpp │ │ ├── alignmentLinkTool.h │ │ ├── attachmentTool.cpp │ │ ├── attachmentTool.h │ │ ├── elasticLinkTool.cpp │ │ ├── elasticLinkTool.h │ │ ├── fixedConstraintTool.cpp │ │ ├── fixedConstraintTool.h │ │ ├── magneticLinkTool.cpp │ │ ├── magneticLinkTool.h │ │ ├── motorConstraintTool.cpp │ │ ├── motorConstraintTool.h │ │ ├── pathTool.cpp │ │ ├── pathTool.h │ │ ├── pistonConstraintTool.cpp │ │ ├── pistonConstraintTool.h │ │ ├── regionSelectionTool.cpp │ │ ├── regionSelectionTool.h │ │ ├── rotationTool.cpp │ │ ├── rotationTool.h │ │ ├── scaleTool.cpp │ │ ├── scaleTool.h │ │ ├── selectionTool.cpp │ │ ├── selectionTool.h │ │ ├── springLinkTool.cpp │ │ ├── springLinkTool.h │ │ ├── toolSpacing.h │ │ ├── translationTool.cpp │ │ └── translationTool.h │ ├── resource.h │ ├── resources.cpp │ ├── resources.h │ ├── shader/ │ │ ├── basicShader.cpp │ │ ├── basicShader.h │ │ ├── shaderBase.cpp │ │ ├── shaderBase.h │ │ ├── shaders.cpp │ │ └── shaders.h │ ├── view/ │ │ ├── camera.cpp │ │ ├── camera.h │ │ ├── debugFrame.cpp │ │ ├── debugFrame.h │ │ ├── ecsFrame.cpp │ │ ├── ecsFrame.h │ │ ├── environmentFrame.cpp │ │ ├── environmentFrame.h │ │ ├── frames.cpp │ │ ├── frames.h │ │ ├── layerFrame.cpp │ │ ├── layerFrame.h │ │ ├── propertiesFrame.cpp │ │ ├── propertiesFrame.h │ │ ├── resourceFrame.cpp │ │ ├── resourceFrame.h │ │ ├── screen.cpp │ │ ├── screen.h │ │ ├── toolbarFrame.cpp │ │ └── toolbarFrame.h │ ├── view.natvis │ ├── worldBuilder.cpp │ ├── worldBuilder.h │ ├── worlds.cpp │ └── worlds.h ├── benchmarks/ │ ├── basicWorld.cpp │ ├── benchmark.cpp │ ├── benchmark.h │ ├── benchmarks.vcxproj │ ├── complexObjectBenchmark.cpp │ ├── ecsBenchmark.cpp │ ├── getBoundsPerformance.cpp │ ├── manyCubesBenchmark.cpp │ ├── rotationBenchmark.cpp │ ├── threadResponseTime.cpp │ ├── worldBenchmark.cpp │ └── worldBenchmark.h ├── engine/ │ ├── core.cpp │ ├── core.h │ ├── ecs/ │ │ └── registry.h │ ├── engine.vcxproj │ ├── event/ │ │ ├── event.h │ │ ├── keyEvent.h │ │ ├── mouseEvent.h │ │ └── windowEvent.h │ ├── input/ │ │ ├── inputHandler.cpp │ │ ├── inputHandler.h │ │ ├── keyboard.cpp │ │ ├── keyboard.h │ │ ├── modifiers.cpp │ │ ├── modifiers.h │ │ ├── mouse.cpp │ │ └── mouse.h │ ├── io/ │ │ ├── export.cpp │ │ ├── export.h │ │ ├── import.cpp │ │ └── import.h │ ├── layer/ │ │ ├── layer.h │ │ ├── layerStack.cpp │ │ └── layerStack.h │ ├── options/ │ │ ├── keyboardOptions.cpp │ │ └── keyboardOptions.h │ ├── resource/ │ │ ├── meshResource.cpp │ │ └── meshResource.h │ └── tool/ │ ├── buttonTool.h │ ├── stateTool.h │ ├── tool.h │ ├── toolManager.cpp │ └── toolManager.h ├── examples/ │ ├── CMakeLists.txt │ ├── examples.vcxproj │ └── openglBasic.cpp ├── graphics/ │ ├── batch/ │ │ ├── batch.h │ │ ├── batchConfig.h │ │ ├── commandBatch.h │ │ ├── guiBatch.h │ │ ├── instanceBatch.h │ │ └── instanceBatchManager.h │ ├── bindable.cpp │ ├── bindable.h │ ├── buffers/ │ │ ├── bufferLayout.cpp │ │ ├── bufferLayout.h │ │ ├── frameBuffer.cpp │ │ ├── frameBuffer.h │ │ ├── indexBuffer.cpp │ │ ├── indexBuffer.h │ │ ├── renderBuffer.cpp │ │ ├── renderBuffer.h │ │ ├── vertexArray.cpp │ │ ├── vertexArray.h │ │ ├── vertexBuffer.cpp │ │ └── vertexBuffer.h │ ├── component.natvis │ ├── core.cpp │ ├── core.h │ ├── debug/ │ │ ├── guiDebug.cpp │ │ ├── guiDebug.h │ │ ├── profilerUI.cpp │ │ ├── profilerUI.h │ │ ├── threePhaseBuffer.h │ │ ├── visualDebug.cpp │ │ └── visualDebug.h │ ├── ecs/ │ │ ├── components.h │ │ └── materials.h │ ├── extendedTriangleMesh.cpp │ ├── extendedTriangleMesh.h │ ├── font.cpp │ ├── font.h │ ├── glfwUtils.cpp │ ├── glfwUtils.h │ ├── graphics.vcxproj │ ├── gui/ │ │ ├── color.h │ │ ├── gui.cpp │ │ ├── gui.h │ │ ├── guiUtils.cpp │ │ ├── guiUtils.h │ │ ├── imgui/ │ │ │ ├── imguiExtension.h │ │ │ ├── imguiStyle.cpp │ │ │ ├── imguiStyle.h │ │ │ ├── legacy_imgui_impl_glfw.cpp │ │ │ ├── legacy_imgui_impl_glfw.h │ │ │ ├── legacy_imgui_impl_opengl3.cpp │ │ │ └── legacy_imgui_impl_opengl3.h │ │ └── orderedVector.h │ ├── legacy/ │ │ ├── button.cpp │ │ ├── button.h │ │ ├── checkBox.cpp │ │ ├── checkBox.h │ │ ├── colorPicker.cpp │ │ ├── colorPicker.h │ │ ├── component.h │ │ ├── container.cpp │ │ ├── container.h │ │ ├── cshader.cpp │ │ ├── cshader.h │ │ ├── directionEditor.cpp │ │ ├── directionEditor.h │ │ ├── frame.cpp │ │ ├── frame.h │ │ ├── gshader.cpp │ │ ├── gshader.h │ │ ├── image.cpp │ │ ├── image.h │ │ ├── label.cpp │ │ ├── label.h │ │ ├── layout.cpp │ │ ├── layout.h │ │ ├── panel.cpp │ │ ├── panel.h │ │ ├── shader.cpp │ │ ├── shader.h │ │ ├── shaderLexer.cpp │ │ ├── shaderLexer.h │ │ ├── shaderParser.cpp │ │ ├── shaderParser.h │ │ ├── slider.cpp │ │ ├── slider.h │ │ ├── text.cpp │ │ └── text.h │ ├── mesh/ │ │ ├── abstractMesh.cpp │ │ ├── abstractMesh.h │ │ ├── arrayMesh.cpp │ │ ├── arrayMesh.h │ │ ├── indexedMesh.cpp │ │ ├── indexedMesh.h │ │ ├── pointMesh.cpp │ │ ├── pointMesh.h │ │ ├── primitive.h │ │ ├── vectorMesh.cpp │ │ └── vectorMesh.h │ ├── meshRegistry.cpp │ ├── meshRegistry.h │ ├── path/ │ │ ├── path.cpp │ │ ├── path.h │ │ ├── path3D.cpp │ │ └── path3D.h │ ├── renderer.cpp │ ├── renderer.h │ ├── resource/ │ │ ├── fontResource.cpp │ │ ├── fontResource.h │ │ ├── shaderResource.cpp │ │ ├── shaderResource.h │ │ ├── textureResource.cpp │ │ └── textureResource.h │ ├── shader/ │ │ ├── lexer.cpp │ │ ├── lexer.h │ │ ├── parser.cpp │ │ ├── parser.h │ │ ├── propertiesParser.cpp │ │ ├── propertiesParser.h │ │ ├── shader.cpp │ │ ├── shader.h │ │ ├── shaders.cpp │ │ └── shaders.h │ ├── texture.cpp │ └── texture.h ├── install/ │ ├── clean.bat │ ├── clean.sh │ ├── setup.bat │ ├── setup.sh │ ├── setupBuild.bat │ ├── setupBuild.sh │ ├── setupBuildUbuntu.sh │ ├── setupDependencies.bat │ ├── setupDependencies.sh │ ├── setupDependenciesUbuntu.sh │ └── setupUbuntu.sh ├── res/ │ ├── default_imgui.ini │ └── shaders/ │ ├── basic.shader │ ├── blur.shader │ ├── compute.shader │ ├── debug.shader │ ├── depth.shader │ ├── depthbuffer.shader │ ├── font.shader │ ├── gui.shader │ ├── instance.shader │ ├── lighting.shader │ ├── line.shader │ ├── mask.shader │ ├── origin.shader │ ├── point.shader │ ├── postprocess.shader │ ├── quad.shader │ ├── sky.shader │ ├── skybox.shader │ ├── test.shader │ └── vector.shader ├── tests/ │ ├── boundsTree2Tests.cpp │ ├── compare.h │ ├── constraintTests.cpp │ ├── ecsTests.cpp │ ├── estimateMotion.cpp │ ├── estimateMotion.h │ ├── estimationTests.cpp │ ├── generators.cpp │ ├── generators.h │ ├── geometryTests.cpp │ ├── guiTests.cpp │ ├── indexedShapeTests.cpp │ ├── inertiaTests.cpp │ ├── jointTests.cpp │ ├── lexerTests.cpp │ ├── mathTests.cpp │ ├── motionTests.cpp │ ├── physicalStructureTests.cpp │ ├── physicsTests.cpp │ ├── randomValues.h │ ├── rotationTests.cpp │ ├── simulation.h │ ├── testFrameworkConsistencyTests.cpp │ ├── testValues.cpp │ ├── testValues.h │ ├── tests.vcxproj │ ├── testsMain.cpp │ └── testsMain.h ├── util/ │ ├── cmdParser.h │ ├── fileUtils.cpp │ ├── fileUtils.h │ ├── iteratorUtils.h │ ├── log.cpp │ ├── log.h │ ├── parseCPUIDArgs.h │ ├── properties.cpp │ ├── properties.h │ ├── resource/ │ │ ├── resource.cpp │ │ ├── resource.h │ │ ├── resourceDescriptor.h │ │ ├── resourceLoader.cpp │ │ ├── resourceLoader.h │ │ ├── resourceManager.cpp │ │ └── resourceManager.h │ ├── stringUtil.cpp │ ├── stringUtil.h │ ├── systemVariables.cpp │ ├── systemVariables.h │ ├── terminalColor.cpp │ ├── terminalColor.h │ ├── tracker.h │ ├── typetraits.h │ ├── util.vcxproj │ ├── valueCycle.cpp │ └── valueCycle.h └── world.grammar
SYMBOL INDEX (2072 symbols across 475 files)
FILE: Physics3D/boundstree/boundsTree.cpp
type P3D (line 6) | namespace P3D {
function OverlapMatrix (line 128) | OverlapMatrix TrunkSIMDHelperFallback::computeBoundsOverlapMatrix(cons...
function OverlapMatrix (line 140) | OverlapMatrix TrunkSIMDHelperFallback::computeInternalBoundsOverlapMat...
function addRecursive (line 293) | int addRecursive(TrunkAllocator& allocator, TreeTrunk& curTrunk, int c...
function containsObjectRecursive (line 320) | bool containsObjectRecursive(const TreeTrunk& trunk, int trunkSize, co...
function removeRecursive (line 341) | int removeRecursive(TrunkAllocator& allocator, TreeTrunk& curTrunk, in...
type TreeGrab (line 380) | struct TreeGrab {
method TreeGrab (line 385) | TreeGrab() : resultingGroupSize(-1) {}
method TreeGrab (line 386) | TreeGrab(int resultingGroupSize, TreeNodeRef&& nodeRef, const Bounds...
function TreeGrab (line 393) | static TreeGrab grabGroupRecursive(TrunkAllocator& allocator, TreeTrun...
method TreeGrab (line 385) | TreeGrab() : resultingGroupSize(-1) {}
method TreeGrab (line 386) | TreeGrab(int resultingGroupSize, TreeNodeRef&& nodeRef, const Bounds...
function TreeNodeRef (line 444) | const TreeNodeRef* getGroupRecursive(const TreeTrunk& curTrunk, int cu...
function freeTrunksRecursive (line 476) | static void freeTrunksRecursive(TrunkAllocator& alloc, TreeTrunk& curT...
function forEachRecurseWithBounds (line 489) | static void forEachRecurseWithBounds(const TreeTrunk& curTrunk, int cu...
function insertGroupIntoGroup (line 502) | static bool insertGroupIntoGroup(TrunkAllocator& sourceAlloc, TrunkAll...
function TrunkAllocator (line 543) | TrunkAllocator& TrunkAllocator::operator=(TrunkAllocator&& other) noex...
function TreeTrunk (line 548) | TreeTrunk* TrunkAllocator::allocTrunk() {
function updateObjectBoundsRecurive (line 645) | static bool updateObjectBoundsRecurive(TreeTrunk& curTrunk, int curTru...
function findAndReplaceObjectRecursive (line 674) | static bool findAndReplaceObjectRecursive(TreeTrunk& curTrunk, int cur...
function disbandGroupRecursive (line 701) | static bool disbandGroupRecursive(TreeTrunk& curTrunk, int curTrunkSiz...
function getSizeRecursive (line 734) | static size_t getSizeRecursive(const TreeTrunk& curTrunk, int curTrunk...
function isLeafTrunk (line 768) | static bool isLeafTrunk(TreeTrunk& trunk, int trunkSize) {
function improveTrunkHorizontal (line 776) | static void improveTrunkHorizontal(TrunkAllocator& alloc, TreeTrunk& t...
function swapNodesBetweenTrunks (line 830) | inline static void swapNodesBetweenTrunks(TreeTrunk& trunkA, int index...
function improveTrunkVertical (line 840) | static void improveTrunkVertical(TreeTrunk& trunk) {
function moveElementsOutOfGroup (line 891) | static int moveElementsOutOfGroup(TrunkAllocator& alloc, TreeTrunk& tr...
function improveStructureRecursive (line 929) | static int improveStructureRecursive(TrunkAllocator& alloc, TreeTrunk&...
FILE: Physics3D/boundstree/boundsTree.h
function namespace (line 18) | namespace P3D {
type TrunkSIMDHelperFallback (line 222) | struct TrunkSIMDHelperFallback {
function class (line 269) | class TrunkAllocator {
function class (line 545) | class BoundsTreeIteratorPrototype {
function IteratorEnd (line 596) | bool operator!=(IteratorEnd) const {
type StackElement (line 603) | struct StackElement {
function delveDown (line 616) | void delveDown() {
function IteratorEnd (line 666) | bool operator!=(IteratorEnd) const {
function class (line 671) | class BoundsTreePrototype {
function size (line 711) | size_t size() const;
function TrunkAllocator (line 816) | inline TrunkAllocator& getAllocator() { return allocator; }
function iter (line 877) | BoundableCastIterator(const UnderlyingIter& iter) : iter(iter) {}
function BoundsTreePrototype (line 891) | inline BoundsTreePrototype& getPrototype() { return tree; }
function mergeGroups (line 948) | void mergeGroups(const Boundable* groupRepA, const Boundable* groupRepB) {
function contains (line 951) | bool contains(const Boundable* object) const {
function groupContains (line 954) | bool groupContains(const Boundable* groupRep, const Boundable* object) c...
function updateObjectBounds (line 958) | void updateObjectBounds(const Boundable* object, const BoundsTemplate<fl...
function updateObjectGroupBounds (line 961) | void updateObjectGroupBounds(const Boundable* groupRep, const BoundsTemp...
function findAndReplaceObject (line 966) | void findAndReplaceObject(const Boundable* oldObject, Boundable* newObje...
function disbandGroup (line 970) | void disbandGroup(const Boundable* groupRep) {
function groupSize (line 977) | size_t groupSize(const Boundable* groupRep) const {
function clear (line 983) | void clear() {
function transferGroupTo (line 987) | void transferGroupTo(const Boundable* groupRep, BoundsTree& destinationT...
function transferTo (line 997) | void transferTo(Boundable* obj, BoundsTree& destinationTree) {
function moveOutOfGroup (line 1003) | void moveOutOfGroup(Boundable* obj) {
function maxImproveStructure (line 1070) | void maxImproveStructure() { tree.maxImproveStructure(); }
type BasicBounded (line 1073) | struct BasicBounded {
FILE: Physics3D/boundstree/boundsTreeAVX.cpp
type P3D (line 6) | namespace P3D {
function OverlapMatrix (line 8) | OverlapMatrix TrunkSIMDHelperFallback::computeBoundsOverlapMatrixAVX(c...
FILE: Physics3D/boundstree/boundsTreeSSE.cpp
type P3D (line 6) | namespace P3D {
function OverlapMatrix (line 8) | OverlapMatrix TrunkSIMDHelperFallback::computeBoundsOverlapMatrixSSE(c...
FILE: Physics3D/boundstree/filters/outOfBoundsFilter.h
function namespace (line 7) | namespace P3D {
function const (line 21) | bool operator()(const Part& part) const {
FILE: Physics3D/boundstree/filters/rayIntersectsBoundsFilter.h
function namespace (line 8) | namespace P3D {
function const (line 22) | bool operator()(const Part& part) const {
FILE: Physics3D/boundstree/filters/visibilityFilter.cpp
type P3D (line 8) | namespace P3D {
function VisibilityFilter (line 14) | VisibilityFilter VisibilityFilter::fromSteps(const Position& origin, c...
function VisibilityFilter (line 25) | VisibilityFilter VisibilityFilter::fromSteps(const Position& origin, c...
function VisibilityFilter (line 36) | VisibilityFilter VisibilityFilter::forWindow(const Position& origin, c...
function VisibilityFilter (line 52) | VisibilityFilter VisibilityFilter::forSubWindow(const Position& origin...
FILE: Physics3D/boundstree/filters/visibilityFilter.h
function namespace (line 7) | namespace P3D {
FILE: Physics3D/colissionBuffer.h
function namespace (line 5) | namespace P3D {
FILE: Physics3D/constraints/ballConstraint.cpp
type P3D (line 4) | namespace P3D {
function makeMatrices (line 9) | static ConstraintMatrixPair<3> makeMatrices(const PhysicalInfo& phys, ...
function ConstraintMatrixPack (line 20) | ConstraintMatrixPack BallConstraint::getMatrices(const PhysicalInfo& p...
FILE: Physics3D/constraints/ballConstraint.h
function namespace (line 6) | namespace P3D {
FILE: Physics3D/constraints/barConstraint.cpp
type P3D (line 4) | namespace P3D {
function makeMatrices (line 9) | static ConstraintMatrixPair<1> makeMatrices(const PhysicalInfo& phys, ...
function ConstraintMatrixPack (line 20) | ConstraintMatrixPack BarConstraint::getMatrices(const PhysicalInfo& ph...
FILE: Physics3D/constraints/barConstraint.h
function namespace (line 7) | namespace P3D {
FILE: Physics3D/constraints/constraint.cpp
type P3D (line 3) | namespace P3D {
FILE: Physics3D/constraints/constraint.h
function namespace (line 3) | namespace P3D {
FILE: Physics3D/constraints/constraintGroup.cpp
type P3D (line 19) | namespace P3D {
function PhysicalInfo (line 23) | static PhysicalInfo getInfo(const Physical& phys) {
function ConstraintMatrixPack (line 28) | ConstraintMatrixPack PhysicalConstraint::getMatrices(double* matrixBuf...
FILE: Physics3D/constraints/constraintGroup.h
function namespace (line 6) | namespace P3D {
FILE: Physics3D/constraints/constraintImpl.h
function namespace (line 10) | namespace P3D {
FILE: Physics3D/constraints/hingeConstraint.cpp
type P3D (line 4) | namespace P3D {
function makeMatrices (line 9) | static ConstraintMatrixPair<5> makeMatrices(const PhysicalInfo& phys, ...
function ConstraintMatrixPack (line 23) | ConstraintMatrixPack HingeConstraint::getMatrices(const PhysicalInfo& ...
FILE: Physics3D/constraints/hingeConstraint.h
function namespace (line 6) | namespace P3D {
FILE: Physics3D/datastructures/alignedPtr.h
function namespace (line 8) | namespace P3D {
FILE: Physics3D/datastructures/aligned_alloc.cpp
type P3D (line 6) | namespace P3D {
function aligned_free (line 14) | void aligned_free(void* ptr) {
FILE: Physics3D/datastructures/aligned_alloc.h
function namespace (line 5) | namespace P3D {
FILE: Physics3D/datastructures/buffers.h
function namespace (line 7) | namespace P3D {
FILE: Physics3D/datastructures/compactPtrDataPair.h
function namespace (line 15) | namespace P3D {
function PtrT (line 100) | PtrT* getPtr() const noexcept {
function setPtr (line 112) | void setPtr(PtrT* ptr) noexcept {
function setData (line 118) | void setData(bool data) noexcept {
function setDataTrue (line 126) | void setDataTrue() noexcept {
function setDataFalse (line 130) | void setDataFalse() noexcept {
function invertData (line 134) | void invertData() noexcept {
FILE: Physics3D/datastructures/iteratorEnd.h
function namespace (line 2) | namespace P3D {
FILE: Physics3D/datastructures/iteratorFactory.h
function namespace (line 5) | namespace P3D {
FILE: Physics3D/datastructures/monotonicTree.h
function namespace (line 9) | namespace P3D {
FILE: Physics3D/datastructures/parallelArray.h
function namespace (line 5) | namespace P3D {
FILE: Physics3D/datastructures/sharedArray.h
function namespace (line 3) | namespace P3D {
FILE: Physics3D/datastructures/smartPointers.h
function namespace (line 6) | namespace P3D {
FILE: Physics3D/datastructures/uniqueArrayPtr.h
function const (line 8) | void operator()(T* arr) const {
type DoNothingDelete (line 12) | struct DoNothingDelete {
function T (line 47) | const T& operator[](std::size_t index) const {
FILE: Physics3D/datastructures/unmanagedArray.h
function T (line 24) | const T& operator[](std::size_t index) const {
FILE: Physics3D/datastructures/unorderedVector.h
function namespace (line 6) | namespace P3D {
FILE: Physics3D/externalforces/directionalGravity.cpp
type P3D (line 8) | namespace P3D {
FILE: Physics3D/externalforces/directionalGravity.h
function namespace (line 6) | namespace P3D {
FILE: Physics3D/externalforces/externalForce.cpp
type P3D (line 7) | namespace P3D {
FILE: Physics3D/externalforces/externalForce.h
function namespace (line 3) | namespace P3D {
FILE: Physics3D/externalforces/magnetForce.cpp
type P3D (line 5) | namespace P3D {
FILE: Physics3D/externalforces/magnetForce.h
function namespace (line 8) | namespace P3D {
FILE: Physics3D/geometry/builtinShapeClasses.cpp
type P3D (line 8) | namespace P3D {
function BoundingBox (line 52) | BoundingBox CubeClass::getBounds(const Rotation& rotation, const Diago...
function Vec3f (line 65) | Vec3f CubeClass::furthestInDirection(const Vec3f& direction) const {
function Polyhedron (line 69) | Polyhedron CubeClass::asPolyhedron() const {
function BoundingBox (line 99) | BoundingBox SphereClass::getBounds(const Rotation& rotation, const Dia...
function Vec3f (line 112) | Vec3f SphereClass::furthestInDirection(const Vec3f& direction) const {
function Polyhedron (line 118) | Polyhedron SphereClass::asPolyhedron() const {
function BoundingBox (line 199) | BoundingBox CylinderClass::getBounds(const Rotation& rotation, const D...
function Vec3f (line 221) | Vec3f CylinderClass::furthestInDirection(const Vec3f& direction) const {
function Polyhedron (line 229) | Polyhedron CylinderClass::asPolyhedron() const {
function BoundingBox (line 298) | BoundingBox WedgeClass::getBounds(const Rotation& rotation, const Diag...
function Vec3f (line 330) | Vec3f WedgeClass::furthestInDirection(const Vec3f& direction) const {
function Polyhedron (line 343) | Polyhedron WedgeClass::asPolyhedron() const {
function BoundingBox (line 396) | BoundingBox CornerClass::getBounds(const Rotation& rotation, const Dia...
function Vec3f (line 426) | Vec3f CornerClass::furthestInDirection(const Vec3f& direction) const {
function Polyhedron (line 438) | Polyhedron CornerClass::asPolyhedron() const {
function BoundingBox (line 452) | BoundingBox PolyhedronShapeClass::getBounds(const Rotation& rotation, ...
function Vec3f (line 461) | Vec3f PolyhedronShapeClass::furthestInDirection(const Vec3f& direction...
function Polyhedron (line 464) | Polyhedron PolyhedronShapeClass::asPolyhedron() const {
function BoundingBox (line 470) | BoundingBox PolyhedronShapeClassAVX::getBounds(const Rotation& rotatio...
function Vec3f (line 473) | Vec3f PolyhedronShapeClassAVX::furthestInDirection(const Vec3f& direct...
function BoundingBox (line 477) | BoundingBox PolyhedronShapeClassSSE::getBounds(const Rotation& rotatio...
function Vec3f (line 480) | Vec3f PolyhedronShapeClassSSE::furthestInDirection(const Vec3f& direct...
function BoundingBox (line 484) | BoundingBox PolyhedronShapeClassSSE4::getBounds(const Rotation& rotati...
function Vec3f (line 487) | Vec3f PolyhedronShapeClassSSE4::furthestInDirection(const Vec3f& direc...
function BoundingBox (line 491) | BoundingBox PolyhedronShapeClassFallback::getBounds(const Rotation& ro...
function Vec3f (line 494) | Vec3f PolyhedronShapeClassFallback::furthestInDirection(const Vec3f& d...
FILE: Physics3D/geometry/builtinShapeClasses.h
function virtual (line 72) | virtual Polyhedron asPolyhedron() const override;
FILE: Physics3D/geometry/computationBuffer.cpp
type P3D (line 6) | namespace P3D {
FILE: Physics3D/geometry/computationBuffer.h
function namespace (line 6) | namespace P3D {
FILE: Physics3D/geometry/convexShapeBuilder.cpp
type P3D (line 10) | namespace P3D {
function moveTriangle (line 30) | void moveTriangle(Triangle* triangleBuf, TriangleNeighbors* neighborBu...
type ConvexTriangleIterator (line 66) | struct ConvexTriangleIterator {
method ConvexTriangleIterator (line 76) | ConvexTriangleIterator(const Vec3f& point, ConvexShapeBuilder& shape...
method markTriangleRemoved (line 78) | void markTriangleRemoved(int triangle) {
method isRemoved (line 83) | bool isRemoved(int triangle) {
method isAbove (line 87) | bool isAbove(Triangle t) {
method recurseTriangle (line 98) | void recurseTriangle(int currentTriangle, int previousTriangle, int ...
method linkTipTriangles (line 127) | void linkTipTriangles(int next, int previous) {
method createTipTriangle (line 132) | void createTipTriangle(int newPointVertex, int previousVertex, int t...
method applyUpdates (line 144) | void applyUpdates(int newPointVertex) {
function Polyhedron (line 251) | Polyhedron ConvexShapeBuilder::toPolyhedron() const {
function IndexedShape (line 254) | IndexedShape ConvexShapeBuilder::toIndexedShape() const {
FILE: Physics3D/geometry/convexShapeBuilder.h
function namespace (line 7) | namespace P3D {
FILE: Physics3D/geometry/genericCollidable.h
function namespace (line 5) | namespace P3D {
FILE: Physics3D/geometry/genericIntersection.cpp
type P3D (line 21) | namespace P3D {
function incDebugTally (line 22) | inline static void incDebugTally(HistoricTally<long long, IterationTim...
function Vec3f (line 32) | static Vec3f getNormalVec(Triangle t, Vec3f* vertices) {
function getDistanceOfTriangleToOriginSquared (line 40) | static double getDistanceOfTriangleToOriginSquared(Triangle t, Vec3f* ...
type NearestSurface (line 44) | struct NearestSurface {
function NearestSurface (line 49) | static NearestSurface getNearestSurface(const ConvexShapeBuilder& buil...
function MinkPoint (line 67) | static MinkPoint getSupport(const ColissionPair& info, const Vec3f& se...
function runGJKTransformed (line 81) | std::optional<Tetrahedron> runGJKTransformed(const ColissionPair& info...
function initializeBuffer (line 207) | void initializeBuffer(const Tetrahedron& s, ComputationBuffers& b) {
function runEPATransformed (line 224) | bool runEPATransformed(const ColissionPair& info, const Tetrahedron& s...
FILE: Physics3D/geometry/genericIntersection.h
function namespace (line 9) | namespace P3D {
FILE: Physics3D/geometry/indexedShape.cpp
type P3D (line 6) | namespace P3D {
function fillNeighborBuf (line 39) | void fillNeighborBuf(const Triangle* triangles, int triangleCount, Tri...
FILE: Physics3D/geometry/indexedShape.h
function namespace (line 6) | namespace P3D {
FILE: Physics3D/geometry/intersection.cpp
type P3D (line 18) | namespace P3D {
function intersectsTransformed (line 19) | std::optional<Intersection> intersectsTransformed(const Shape& first, ...
function intersectsTransformed (line 25) | std::optional<Intersection> intersectsTransformed(const GenericCollida...
FILE: Physics3D/geometry/intersection.h
function namespace (line 9) | namespace P3D {
FILE: Physics3D/geometry/polyhedron.cpp
type P3D (line 8) | namespace P3D {
function Polyhedron (line 31) | Polyhedron Polyhedron::translated(Vec3f offset) const { return Polyhed...
function Polyhedron (line 32) | Polyhedron Polyhedron::rotated(Rotationf rotation) const { return Poly...
function Polyhedron (line 33) | Polyhedron Polyhedron::localToGlobal(CFramef frame) const { return Pol...
function Polyhedron (line 34) | Polyhedron Polyhedron::globalToLocal(CFramef frame) const { return Pol...
function Polyhedron (line 35) | Polyhedron Polyhedron::scaled(float scaleX, float scaleY, float scaleZ...
function Polyhedron (line 36) | Polyhedron Polyhedron::scaled(DiagonalMat3f scale) const { return Poly...
function Polyhedron (line 37) | Polyhedron Polyhedron::translatedAndScaled(Vec3f translation, Diagonal...
function Vec3 (line 79) | Vec3 Polyhedron::getCenterOfMass() const {
function ScalableInertialMatrix (line 107) | ScalableInertialMatrix Polyhedron::getScalableInertia(const CFrame& re...
function ScalableInertialMatrix (line 146) | ScalableInertialMatrix Polyhedron::getScalableInertiaAroundCenterOfMas...
function SymmetricMat3 (line 160) | SymmetricMat3 Polyhedron::getInertia(const CFrame& reference) const {
function SymmetricMat3 (line 164) | SymmetricMat3 Polyhedron::getInertiaAroundCenterOfMass() const {
FILE: Physics3D/geometry/polyhedron.h
function namespace (line 11) | namespace P3D {
FILE: Physics3D/geometry/scalableInertialMatrix.h
function namespace (line 6) | namespace P3D {
FILE: Physics3D/geometry/shape.cpp
type P3D (line 6) | namespace P3D {
function Shape (line 41) | Shape Shape::scaled(const DiagonalMat3& scale) const {
function Shape (line 44) | Shape Shape::scaled(double scaleX, double scaleY, double scaleZ) const {
function BoundingBox (line 47) | BoundingBox Shape::getBounds() const {
function BoundingBox (line 50) | BoundingBox Shape::getBounds(const Rotation& referenceFrame) const {
function Vec3 (line 53) | Vec3 Shape::getCenterOfMass() const {
function SymmetricMat3 (line 56) | SymmetricMat3 Shape::getInertia() const {
function Vec3f (line 65) | Vec3f Shape::furthestInDirection(const Vec3f& direction) const {
function Polyhedron (line 69) | Polyhedron Shape::asPolyhedron() const {
FILE: Physics3D/geometry/shape.h
function namespace (line 11) | namespace P3D {
FILE: Physics3D/geometry/shapeBuilder.cpp
type P3D (line 3) | namespace P3D {
function Polyhedron (line 56) | Polyhedron ShapeBuilder::toPolyhedron() const {
function IndexedShape (line 60) | IndexedShape ShapeBuilder::toIndexedShape() const {
FILE: Physics3D/geometry/shapeBuilder.h
function namespace (line 6) | namespace P3D {
FILE: Physics3D/geometry/shapeClass.cpp
type P3D (line 3) | namespace P3D {
FILE: Physics3D/geometry/shapeClass.h
function namespace (line 12) | namespace P3D {
FILE: Physics3D/geometry/shapeCreation.cpp
type P3D (line 11) | namespace P3D {
function Shape (line 12) | Shape boxShape(double width, double height, double depth) {
function Shape (line 16) | Shape wedgeShape(double width, double height, double depth) {
function Shape (line 20) | Shape cornerShape(double width, double height, double depth) {
function Shape (line 24) | Shape sphereShape(double radius) {
function Shape (line 28) | Shape cylinderShape(double radius, double height) {
function Shape (line 33) | Shape polyhedronShape(const Polyhedron& poly) {
FILE: Physics3D/geometry/shapeCreation.h
function namespace (line 5) | namespace P3D {
FILE: Physics3D/geometry/shapeLibrary.cpp
type P3D::ShapeLibrary (line 11) | namespace P3D::ShapeLibrary {
function Polyhedron (line 125) | Polyhedron createBox(float width, float height, float depth) {
function Polyhedron (line 143) | Polyhedron createCube(float side) {
function createTriangleRing (line 147) | static void createTriangleRing(int ring1Start, int ring2Start, int siz...
function createTriangleRingReverse (line 157) | static void createTriangleRingReverse(int ring1Start, int ring2Start, ...
function createTriangleFan (line 167) | static void createTriangleFan(int topIndex, int startFan, int size, Ed...
function createTriangleFanReverse (line 173) | static void createTriangleFanReverse(int topIndex, int startFan, int s...
function createTriangleCone (line 179) | static void createTriangleCone(int topIndex, int startFan, int size, E...
function createTriangleConeReverse (line 184) | static void createTriangleConeReverse(int topIndex, int startFan, int ...
function createFlatSurface (line 189) | static void createFlatSurface(int startFan, int size, EditableMesh& me...
function createFlatSurfaceReverse (line 193) | static void createFlatSurfaceReverse(int startFan, int size, EditableM...
function Polyhedron (line 197) | Polyhedron createPrism(int sides, float radius, float height) {
function Polyhedron (line 227) | Polyhedron createPointyPrism(int sides, float radius, float height, fl...
function tesselate (line 262) | static std::pair<Vec3f*, Triangle*> tesselate(Vec3f* vecBuf, Triangle*...
function Polyhedron (line 312) | Polyhedron createSphere(float radius, int steps) {
function Polyhedron (line 357) | Polyhedron createSpikeBall(float internalRadius, float spikeRadius, in...
function Polyhedron (line 412) | Polyhedron createTorus(float ringRadius, float radiusOfTube, int radia...
function Polyhedron (line 439) | Polyhedron createRevolvedShape(float startZ, Vec2f* inbetweenPoints, i...
FILE: Physics3D/geometry/shapeLibrary.h
function namespace (line 5) | namespace P3D::ShapeLibrary {
FILE: Physics3D/geometry/triangleMesh.cpp
type P3D (line 13) | namespace P3D {
function getOffset (line 15) | static size_t getOffset(size_t size) {
function createParallelVecBuf (line 20) | static UniqueAlignedPointer<float> createParallelVecBuf(size_t size) {
function createParallelTriangleBuf (line 23) | static UniqueAlignedPointer<int> createParallelTriangleBuf(size_t size) {
function copy (line 28) | static UniqueAlignedPointer<T> copy(const UniqueAlignedPointer<T>& buf...
function fixFinalBlock (line 40) | static void fixFinalBlock(T* buf, size_t size) {
function MeshPrototype (line 92) | MeshPrototype& MeshPrototype::operator=(const MeshPrototype& mesh) {
function Vec3f (line 125) | Vec3f MeshPrototype::getVertex(int index) const {
function Triangle (line 131) | Triangle MeshPrototype::getTriangle(int index) const {
function TriangleMesh (line 297) | TriangleMesh TriangleMesh::translated(Vec3f offset) const {
function TriangleMesh (line 305) | TriangleMesh TriangleMesh::rotated(Rotationf rotation) const {
function TriangleMesh (line 313) | TriangleMesh TriangleMesh::localToGlobal(CFramef frame) const {
function TriangleMesh (line 321) | TriangleMesh TriangleMesh::globalToLocal(CFramef frame) const {
function TriangleMesh (line 328) | TriangleMesh TriangleMesh::scaled(float scaleX, float scaleY, float sc...
function TriangleMesh (line 336) | TriangleMesh TriangleMesh::scaled(DiagonalMat3f scale) const {
function TriangleMesh (line 340) | TriangleMesh TriangleMesh::translatedAndScaled(Vec3f translation, Diag...
function Vec3f (line 350) | Vec3f TriangleMesh::getNormalVecOfTriangle(Triangle triangle) const {
function CircumscribingSphere (line 377) | CircumscribingSphere TriangleMesh::getCircumscribingSphere() const {
function TriangleMesh (line 472) | TriangleMesh stripUnusedVertices(const Vec3f* vertices, const Triangle...
function Vec3f (line 532) | Vec3f TriangleMesh::furthestInDirectionFallback(const Vec3f& direction...
function BoundingBox (line 547) | BoundingBox TriangleMesh::getBoundsFallback() const {
function BoundingBox (line 566) | BoundingBox TriangleMesh::getBoundsFallback(const Mat3f& referenceFram...
function Vec3f (line 592) | Vec3f TriangleMesh::furthestInDirection(const Vec3f& direction) const {
function BoundingBox (line 606) | BoundingBox TriangleMesh::getBounds() const {
function BoundingBox (line 616) | BoundingBox TriangleMesh::getBounds(const Mat3f& referenceFrame) const {
FILE: Physics3D/geometry/triangleMesh.h
function namespace (line 11) | namespace P3D {
function Triangle (line 22) | [[nodiscard]] Triangle leftShift() const { return Triangle{secondIndex, ...
type ShapeVertexIter (line 29) | struct ShapeVertexIter {
type ShapeTriangleIter (line 46) | struct ShapeTriangleIter {
function class (line 69) | class MeshPrototype {
function class (line 90) | class EditableMesh : public MeshPrototype {
FILE: Physics3D/geometry/triangleMeshAVX.cpp
type P3D (line 7) | namespace P3D {
function __m256i (line 8) | inline __m256i _mm256_blendv_epi32(__m256i a, __m256i b, __m256 mask) {
function mm256_extract_epi32_var_indx (line 18) | inline uint32_t mm256_extract_epi32_var_indx(__m256i vec, int i) {
function Vec3f (line 67) | Vec3f TriangleMesh::furthestInDirectionAVX(const Vec3f& direction) con...
function BoundingBox (line 124) | inline static BoundingBox toBounds(__m256 xMin, __m256 xMax, __m256 yM...
function BoundingBox (line 148) | BoundingBox TriangleMesh::getBoundsAVX() const {
function BoundingBox (line 181) | BoundingBox TriangleMesh::getBoundsAVX(const Mat3f& referenceFrame) co...
FILE: Physics3D/geometry/triangleMeshCommon.h
function namespace (line 6) | namespace P3D {
FILE: Physics3D/geometry/triangleMeshSSE.cpp
type P3D (line 7) | namespace P3D {
function __m128 (line 10) | static __m128 custom_blendv_ps(__m128 a, __m128 b, __m128 mask) {
function __m128i (line 15) | static __m128i custom_blendv_epi32(__m128i a, __m128i b, __m128i mask) {
function BoundingBox (line 19) | static BoundingBox toBounds(__m128 xMin, __m128 xMax, __m128 yMin, __m...
function BoundingBox (line 51) | BoundingBox TriangleMesh::getBoundsSSE() const {
function BoundingBox (line 115) | BoundingBox TriangleMesh::getBoundsSSE(const Mat3f& referenceFrame) co...
function Vec3f (line 282) | Vec3f TriangleMesh::furthestInDirectionSSE(const Vec3f& direction) con...
FILE: Physics3D/geometry/triangleMeshSSE4.cpp
type P3D (line 7) | namespace P3D {
function Vec3f (line 94) | Vec3f TriangleMesh::furthestInDirectionSSE4(const Vec3f& direction) co...
FILE: Physics3D/hardconstraints/constraintTemplates.h
function namespace (line 12) | namespace P3D {
FILE: Physics3D/hardconstraints/controller/constController.h
function namespace (line 5) | namespace P3D {
FILE: Physics3D/hardconstraints/controller/sineWaveController.cpp
type P3D (line 6) | namespace P3D {
FILE: Physics3D/hardconstraints/controller/sineWaveController.h
function namespace (line 6) | namespace P3D {
FILE: Physics3D/hardconstraints/fixedConstraint.cpp
type P3D (line 3) | namespace P3D {
function CFrame (line 6) | CFrame FixedConstraint::getRelativeCFrame() const { return CFrame(0.0,...
function RelativeMotion (line 7) | RelativeMotion FixedConstraint::getRelativeMotion() const { return Rel...
FILE: Physics3D/hardconstraints/fixedConstraint.h
function namespace (line 4) | namespace P3D {
FILE: Physics3D/hardconstraints/hardConstraint.cpp
type P3D (line 3) | namespace P3D {
function CFrame (line 4) | CFrame HardConstraint::getRelativeCFrame() const {
FILE: Physics3D/hardconstraints/hardConstraint.h
function namespace (line 11) | namespace P3D {
FILE: Physics3D/hardconstraints/hardPhysicalConnection.cpp
type P3D (line 3) | namespace P3D {
function CFrame (line 10) | CFrame HardPhysicalConnection::getRelativeCFrameToParent() const {
function RelativeMotion (line 14) | RelativeMotion HardPhysicalConnection::getRelativeMotion() const {
function HardPhysicalConnection (line 24) | HardPhysicalConnection HardPhysicalConnection::inverted()&& {
FILE: Physics3D/hardconstraints/hardPhysicalConnection.h
function namespace (line 10) | namespace P3D {
FILE: Physics3D/hardconstraints/motorConstraint.cpp
type P3D (line 8) | namespace P3D {
FILE: Physics3D/hardconstraints/motorConstraint.h
function namespace (line 6) | namespace P3D {
FILE: Physics3D/hardconstraints/sinusoidalPistonConstraint.h
function namespace (line 6) | namespace P3D {
FILE: Physics3D/inertia.cpp
type P3D (line 6) | namespace P3D {
function SymmetricMat3 (line 7) | SymmetricMat3 getRotatedInertia(const SymmetricMat3& originalInertia, ...
function SymmetricMat3 (line 11) | SymmetricMat3 getTranslatedInertia(const SymmetricMat3& originalInerti...
function SymmetricMat3 (line 21) | SymmetricMat3 getTranslatedInertiaAroundCenterOfMass(const SymmetricMa...
function SymmetricMat3 (line 26) | SymmetricMat3 getTransformedInertia(const SymmetricMat3& originalInert...
function getTranslatedInertiaDerivativesAroundCenterOfMass (line 36) | FullTaylor<SymmetricMat3> getTranslatedInertiaDerivativesAroundCenterO...
function getRotatedInertiaTaylor (line 48) | FullTaylor<SymmetricMat3> getRotatedInertiaTaylor(const SymmetricMat3&...
function SymmetricMat3 (line 68) | SymmetricMat3 getTransformedInertiaAroundCenterOfMass(const SymmetricM...
function SymmetricMat3 (line 77) | SymmetricMat3 getTransformedInertiaAroundCenterOfMass(const SymmetricM...
function getTransformedInertiaDerivativesAroundCenterOfMass (line 88) | FullTaylor<SymmetricMat3> getTransformedInertiaDerivativesAroundCenter...
function getTransformedInertiaDerivativesAroundCenterOfMass (line 100) | FullTaylor<SymmetricMat3> getTransformedInertiaDerivativesAroundCenter...
FILE: Physics3D/inertia.h
function namespace (line 9) | namespace P3D {
FILE: Physics3D/layer.cpp
type P3D (line 10) | namespace P3D {
function WorldLayer (line 28) | WorldLayer& WorldLayer::operator=(WorldLayer&& other) noexcept {
function addMotorPhysToGroup (line 54) | static void addMotorPhysToGroup(BoundsTree<Part>& tree, MotorizedPhysi...
function WorldLayer (line 131) | WorldLayer* getLayerByID(std::vector<ColissionLayer>& knownLayers, int...
function WorldLayer (line 134) | const WorldLayer* getLayerByID(const std::vector<ColissionLayer>& know...
function getMaxLayerID (line 137) | int getMaxLayerID(const std::vector<ColissionLayer>& knownLayers) {
function ColissionLayer (line 155) | ColissionLayer& ColissionLayer::operator=(ColissionLayer&& other) noex...
function boundsSphereEarlyEnd (line 175) | static bool boundsSphereEarlyEnd(const DiagonalMat3& scale, const Vec3...
function runColissionPreTests (line 179) | static bool runColissionPreTests(const Part& p1, const Part& p2) {
function findColissionsBetween (line 197) | static void findColissionsBetween(std::vector<Colission>& colissions, ...
function findColissionsInternal (line 202) | static void findColissionsInternal(std::vector<Colission>& colissions,...
function getColissionsBetween (line 212) | void getColissionsBetween(const ColissionLayer& a, const ColissionLaye...
FILE: Physics3D/layer.h
function namespace (line 9) | namespace P3D {
function optimize (line 55) | void optimize() {
function class (line 76) | class ColissionLayer {
FILE: Physics3D/math/boundingBox.h
function namespace (line 5) | namespace P3D {
FILE: Physics3D/math/bounds.h
function namespace (line 8) | namespace P3D {
type BoundsTemplate (line 109) | typedef BoundsTemplate<Fix<32>> Bounds;
FILE: Physics3D/math/cframe.h
function namespace (line 6) | namespace P3D {
FILE: Physics3D/math/constants.h
function namespace (line 5) | namespace P3D {
FILE: Physics3D/math/fix.h
function namespace (line 5) | namespace P3D {
FILE: Physics3D/math/globalCFrame.h
function namespace (line 7) | namespace P3D {
FILE: Physics3D/math/globalTransform.h
function namespace (line 8) | namespace P3D {
FILE: Physics3D/math/linalg/commonMatrices.h
function namespace (line 7) | namespace P3D {
FILE: Physics3D/math/linalg/eigen.cpp
type P3D (line 5) | namespace P3D {
function update (line 7) | void update(EigenValues<N, 3>& e, bool* changed, int k, N t) {
function rotateEigen (line 13) | void rotateEigen(Matrix<N, 3, 3>& copy, int k, int l, int i, int j, N ...
function getEigenDecomposition (line 20) | EigenSet<double, 3> getEigenDecomposition(const SymmetricMat3& sm) {
FILE: Physics3D/math/linalg/eigen.h
function namespace (line 7) | namespace P3D {
FILE: Physics3D/math/linalg/largeMatrix.h
function namespace (line 7) | namespace P3D {
function UnmanagedLargeVector (line 48) | inline UnmanagedLargeVector<T> subVector(size_t offset, size_t size) {
function UnmanagedLargeVector (line 52) | inline UnmanagedLargeVector<const T> subVector(size_t offset, size_t siz...
function T (line 143) | const T& operator()(size_t row, size_t col) const {
function setSubMatrix (line 149) | void setSubMatrix(size_t topLeftRow, size_t topLeftCol, const UnmanagedL...
function T (line 209) | T* begin() {return data;}
function T (line 210) | T* end() {return data + w * h;}
function T (line 211) | const T* begin() const { return data; }
function T (line 212) | const T* end() const { return data + w * h; }
function LargeMatrix (line 250) | static LargeMatrix zero(size_t width, size_t height) {
function getAmountOfElementsForSymmetric (line 259) | constexpr size_t getAmountOfElementsForSymmetric(size_t size) {
function T (line 341) | const T& operator()(size_t row, size_t col) const {
function setCol (line 419) | void setCol(size_t col, const Vector<T, Rows>& value) {
function T (line 455) | const T& operator()(size_t row, size_t col) const {
function T (line 459) | T* begin() { return data; }
function T (line 460) | const T* begin() const { return data; }
function T (line 461) | T* end() { return data + cols*Rows; }
function T (line 462) | const T* end() const { return data + cols*Rows; }
function setRow (line 525) | void setRow(size_t row, const Vector<T, Cols>& value) {
function T (line 568) | const T& operator()(size_t row, size_t col) const {
function T (line 572) | T* begin() { return data; }
function T (line 573) | const T* begin() const { return data; }
function T (line 574) | T* end() { return data + rows * Cols; }
function T (line 575) | const T* end() const { return data + rows * Cols; }
FILE: Physics3D/math/linalg/largeMatrixAlgorithms.h
function namespace (line 11) | namespace P3D {
function swapRows (line 29) | static void swapRows(UnmanagedVerticalFixedMatrix<T, Rows>& m, std::size...
function subtractRowsFactorTimes (line 46) | static void subtractRowsFactorTimes(UnmanagedHorizontalFixedMatrix<T, Co...
function subtractRowsFactorTimes (line 52) | static void subtractRowsFactorTimes(UnmanagedVerticalFixedMatrix<T, Rows...
function multiplyRowBy (line 69) | static void multiplyRowBy(UnmanagedHorizontalFixedMatrix<T, Cols>& m, st...
function multiplyRowBy (line 75) | static void multiplyRowBy(UnmanagedVerticalFixedMatrix<T, Rows>& m, std:...
function getHeight (line 90) | static std::size_t getHeight(UnmanagedHorizontalFixedMatrix<T, Cols>& m) {
function getHeight (line 94) | static std::size_t getHeight(UnmanagedVerticalFixedMatrix<T, Rows>& m) {
FILE: Physics3D/math/linalg/mat.h
function namespace (line 11) | namespace P3D {
function setDataRowMajor (line 98) | void setDataRowMajor(const T* data) {
function setDataColMajor (line 105) | void setDataColMajor(const T* data) {
function setSubMatrix (line 139) | void setSubMatrix(const Matrix<T, SubHeight, SubWidth>& mat, std::size_t...
function setRow (line 223) | void setRow(std::size_t row, const Vector<T, Width>& data) {
function setCol (line 230) | void setCol(std::size_t col, const Vector<T, Height>& data) {
function toColMajorData (line 288) | void toColMajorData(T* buf) const {
function toRowMajorData (line 296) | void toRowMajorData(T* buf) const {
function SymmetricMatrix (line 320) | size_t Size>
function T (line 334) | inline constexpr T operator()(std::size_t row, std::size_t col) const {
function data (line 355) | inline constexpr SymmetricMatrix(const std::initializer_list<T>& list) :...
function DiagonalMatrix (line 442) | size_t Size>
type Matrix (line 558) | typedef Matrix<double, 2, 2> Mat2;
type Matrix (line 559) | typedef Matrix<float, 2, 2> Mat2f;
type Mat2l (line 560) | typedef Matrix<long long, 2, 2> Mat2l;
type Matrix (line 561) | typedef Matrix<double, 2, 2> RotMat2;
type Matrix (line 564) | typedef Matrix<double, 3, 3> Mat3;
type Matrix (line 565) | typedef Matrix<float, 3, 3> Mat3f;
type Mat3l (line 566) | typedef Matrix<long long, 3, 3> Mat3l;
type SymmetricMatrix (line 568) | typedef SymmetricMatrix<double, 3> SymmetricMat3;
type SymmetricMatrix (line 569) | typedef SymmetricMatrix<float, 3> SymmetricMat3f;
type SymmetricMat3l (line 570) | typedef SymmetricMatrix<long long, 3> SymmetricMat3l;
type DiagonalMatrix (line 572) | typedef DiagonalMatrix<double, 3> DiagonalMat3;
type DiagonalMatrix (line 573) | typedef DiagonalMatrix<float, 3> DiagonalMat3f;
type DiagonalMat3l (line 574) | typedef DiagonalMatrix<long long, 3> DiagonalMat3l;
type Matrix (line 577) | typedef Matrix<double, 4, 4> Mat4;
type Matrix (line 578) | typedef Matrix<float, 4, 4> Mat4f;
type Mat4l (line 579) | typedef Matrix<long long, 4, 4> Mat4l;
function det (line 589) | size_t Size>
function det (line 616) | size_t Size>
function det (line 620) | size_t Size>
FILE: Physics3D/math/linalg/quat.h
function namespace (line 7) | namespace P3D {
type Quaternion (line 46) | typedef Quaternion<double> Quat4;
type Quaternion (line 47) | typedef Quaternion<float> Quat4f;
type Quat4l (line 48) | typedef Quaternion<long long> Quat4l;
type Quaternion (line 49) | typedef Quaternion<int> Quat4i;
FILE: Physics3D/math/linalg/trigonometry.cpp
type P3D (line 6) | namespace P3D {
function rotate (line 8) | Matrix<T, 4, 4> rotate(const Matrix<T, 4, 4>& mat, T angle, T x, T y, ...
function Mat4f (line 28) | Mat4f ortho(float left, float right, float bottom, float top, float zN...
function Mat4f (line 45) | Mat4f perspective(float fov, float aspect, float zNear, float zFar) {
function Mat4f (line 60) | Mat4f lookAt(const Vec3f& from, const Vec3f& to, const Vec3f& up) {
FILE: Physics3D/math/linalg/trigonometry.h
function equalsApproximately (line 359) | inline bool equalsApproximately(double value, double comparedTo) {
function equalsApproximately (line 363) | inline bool equalsApproximately(float value, float comparedTo) {
FILE: Physics3D/math/linalg/vec.h
function namespace (line 7) | namespace P3D {
type Vector (line 213) | typedef Vector<double, 1> Vec1;
type Vector (line 214) | typedef Vector<float, 1> Vec1f;
type Vec1l (line 215) | typedef Vector<long long, 1> Vec1l;
type Vector (line 216) | typedef Vector<int, 1> Vec1i;
type Vector (line 218) | typedef Vector<double, 2> Vec2;
type Vector (line 219) | typedef Vector<float, 2> Vec2f;
type Vec2l (line 220) | typedef Vector<long long, 2> Vec2l;
type Vector (line 221) | typedef Vector<int, 2> Vec2i;
type Vector (line 223) | typedef Vector<double, 3> Vec3;
type Vector (line 224) | typedef Vector<float, 3> Vec3f;
type Vec3l (line 225) | typedef Vector<long long, 3> Vec3l;
type Vector (line 226) | typedef Vector<int, 3> Vec3i;
type Vector (line 228) | typedef Vector<double, 4> Vec4;
type Vector (line 229) | typedef Vector<float, 4> Vec4f;
type Vec4l (line 230) | typedef Vector<long long, 4> Vec4l;
type Vector (line 231) | typedef Vector<int, 4> Vec4i;
type Vector (line 233) | typedef Vector<double, 5> Vec5;
type Vector (line 234) | typedef Vector<float, 5> Vec5f;
type Vec5l (line 235) | typedef Vector<long long, 5> Vec5l;
type Vector (line 236) | typedef Vector<int, 5> Vec5i;
type Vector (line 238) | typedef Vector<double, 6> Vec6;
type Vector (line 239) | typedef Vector<float, 6> Vec6f;
type Vec6l (line 240) | typedef Vector<long long, 6> Vec6l;
type Vector (line 241) | typedef Vector<int, 6> Vec6i;
function isLongerThan (line 453) | constexpr bool isLongerThan(const Vector<T1, Size>& vec, const T2& lengt...
function isShorterThan (line 458) | constexpr bool isShorterThan(const Vector<T1, Size>& vec, const T2& leng...
FILE: Physics3D/math/mathUtil.h
function namespace (line 5) | namespace P3D {
FILE: Physics3D/math/position.h
function namespace (line 6) | namespace P3D {
FILE: Physics3D/math/predefinedTaylorExpansions.h
function T (line 19) | T values[4]{cosValue, -sinValue, -cosValue, sinValue};
function T (line 38) | T values[4]{-sinValue, -cosValue, sinValue, cosValue};
function T (line 55) | T values[4]{cosValue, -sinValue, -cosValue, sinValue};
function T (line 73) | T values[4]{-sinValue, -cosValue, sinValue, cosValue};
FILE: Physics3D/math/ray.h
function namespace (line 7) | namespace P3D {
function doRayAndBoundsIntersect (line 117) | inline bool doRayAndBoundsIntersect(const Bounds& bounds, const Ray& ray) {
FILE: Physics3D/math/rotation.h
function namespace (line 11) | namespace P3D {
FILE: Physics3D/math/taylorExpansion.h
function namespace (line 7) | namespace P3D {
type TaylorExpansion (line 31) | struct TaylorExpansion {
function T (line 37) | T* begin() { return derivs.begin(); }
function T (line 38) | const T* begin() const { return derivs.begin(); }
function T (line 39) | T* end() { return derivs.end(); }
function T (line 40) | const T* end() const { return derivs.end(); }
function T (line 70) | inline const T& getDerivative(std::size_t i) const { return derivs[i+1]; }
function setConstantValue (line 72) | inline void setConstantValue(const T& newConstValue) { derivs[0] = newCo...
function setDerivative (line 73) | inline void setDerivative(std::size_t i, const T& newDerivative) { deriv...
function pascalIndex (line 381) | constexpr int pascalIndex(int layer, int index) {
function else (line 394) | else if constexpr(Index == Layer) {
function computeDerivatives (line 402) | void computeDerivatives(const Derivatives<T1, Size>& first, const Deriva...
FILE: Physics3D/math/transform.h
function namespace (line 7) | namespace P3D {
function TransformTemplate (line 47) | inline TransformTemplate<T> localToGlobal(TransformTemplate<T> lFrame) c...
function TransformTemplate (line 51) | inline TransformTemplate<T> globalToLocal(const TransformTemplate<T>& gF...
function TransformTemplate (line 55) | inline TransformTemplate<T> localToRelative(const TransformTemplate<T>& ...
function TransformTemplate (line 59) | inline TransformTemplate<T> relativeToLocal(const TransformTemplate<T>& ...
function transformGlobalSide (line 97) | void transformGlobalSide(const Matrix<T, 3, 3>& transformation) {
function transformLocalSide (line 101) | void transformLocalSide(const Matrix<T, 3, 3>& transformation) {
type TransformTemplate (line 120) | typedef TransformTemplate<double> Transform;
type TransformTemplate (line 121) | typedef TransformTemplate<float> Transformf;
FILE: Physics3D/math/utils.h
function namespace (line 5) | namespace P3D {
FILE: Physics3D/misc/catchable_assert.h
function namespace (line 6) | namespace P3D {
FILE: Physics3D/misc/cpuid.cpp
type P3D (line 9) | namespace P3D {
class CPUID (line 10) | class CPUID {
method CPUID (line 14) | explicit CPUID(unsigned i, unsigned ecx) {
FILE: Physics3D/misc/cpuid.h
function namespace (line 3) | namespace P3D {
FILE: Physics3D/misc/debug.cpp
type P3D (line 13) | namespace P3D {
type Debug (line 14) | namespace Debug {
function logVector (line 23) | void logVector(Position origin, Vec3 vec, VectorType type) { logVecA...
function logPoint (line 24) | void logPoint(Position point, PointType type) { logPointAction(point...
function logCFrame (line 25) | void logCFrame(CFrame frame, CFrameType type) { logCFrameAction(fram...
function logShape (line 26) | void logShape(const Polyhedron& shape, const GlobalCFrame& location)...
function log (line 27) | void log(const char* format, ...) {
function logWarn (line 33) | void logWarn(const char* format, ...) {
function logError (line 39) | void logError(const char* format, ...) {
function setVectorLogAction (line 46) | void setVectorLogAction(void(*logger)(Position origin, Vec3 vec, Vec...
function setPointLogAction (line 47) | void setPointLogAction(void(*logger)(Position point, PointType type)...
function setCFrameLogAction (line 48) | void setCFrameLogAction(void(*logger)(CFrame frame, CFrameType type)...
function setShapeLogAction (line 49) | void setShapeLogAction(void(*logger)(const Polyhedron& shape, const ...
function setLogAction (line 50) | void setLogAction(void(*logger)(const char* format, std::va_list arg...
function setLogWarnAction (line 51) | void setLogWarnAction(void(*logger)(const char* format, std::va_list...
function setLogErrorAction (line 52) | void setLogErrorAction(void(*logger)(const char* format, std::va_lis...
function saveIntersectionError (line 55) | void saveIntersectionError(const Part& first, const Part& second, co...
FILE: Physics3D/misc/debug.h
function namespace (line 10) | namespace P3D {
FILE: Physics3D/misc/physicsProfiler.cpp
type P3D (line 3) | namespace P3D {
FILE: Physics3D/misc/physicsProfiler.h
type class (line 6) | enum class
type class (line 23) | enum class
function IterationTime (line 31) | enum class IterationTime {
FILE: Physics3D/misc/profiling.h
function namespace (line 9) | namespace P3D {
FILE: Physics3D/misc/serialization/dynamicSerialize.h
function namespace (line 5) | namespace P3D {
FILE: Physics3D/misc/serialization/serialization.cpp
type P3D (line 25) | namespace P3D {
function serializePolyhedron (line 30) | void serializePolyhedron(const Polyhedron& poly, std::ostream& ostream) {
function Polyhedron (line 41) | Polyhedron deserializePolyhedron(std::istream& istream) {
function Shape (line 72) | Shape ShapeDeserializer::deserializeShape(std::istream& istream) const {
function serializeFixedConstraint (line 80) | void serializeFixedConstraint(const FixedConstraint& object, std::ostr...
function FixedConstraint (line 81) | FixedConstraint* deserializeFixedConstraint(std::istream& istream) { r...
function serializeMotorConstraint (line 83) | void serializeMotorConstraint(const ConstantSpeedMotorConstraint& cons...
function ConstantSpeedMotorConstraint (line 87) | ConstantSpeedMotorConstraint* deserializeMotorConstraint(std::istream&...
function serializePistonConstraint (line 94) | void serializePistonConstraint(const SinusoidalPistonConstraint& const...
function SinusoidalPistonConstraint (line 100) | SinusoidalPistonConstraint* deserializePistonConstraint(std::istream& ...
function serializeSinusoidalMotorConstraint (line 111) | void serializeSinusoidalMotorConstraint(const MotorConstraintTemplate<...
function serializeBallConstraint (line 129) | void serializeBallConstraint(const BallConstraint& constraint, std::os...
function BallConstraint (line 134) | BallConstraint* deserializeBallConstraint(std::istream& istream) {
function serializeHingeConstraint (line 141) | void serializeHingeConstraint(const HingeConstraint& constraint, std::...
function HingeConstraint (line 148) | HingeConstraint* deserializeHingeConstraint(std::istream& istream) {
function serializeBarConstraint (line 157) | void serializeBarConstraint(const BarConstraint& constraint, std::ostr...
function BarConstraint (line 163) | BarConstraint* deserializeBarConstraint(std::istream& istream) {
function serializePolyhedronShapeClass (line 171) | void serializePolyhedronShapeClass(const PolyhedronShapeClass& polyhed...
function PolyhedronShapeClass (line 174) | PolyhedronShapeClass* deserializePolyhedronShapeClass(std::istream& is...
function serializeDirectionalGravity (line 180) | void serializeDirectionalGravity(const DirectionalGravity& gravity, st...
function DirectionalGravity (line 183) | DirectionalGravity* deserializeDirectionalGravity(std::istream& istrea...
function serializeLayer (line 192) | static void serializeLayer(const Part& part, std::ostream& ostream) {
function WorldLayer (line 195) | static WorldLayer* deserializeLayer(std::vector<ColissionLayer>& known...
function Part (line 209) | Part* DeSerializationSessionPrototype::deserializePartData(const Globa...
function Part (line 216) | Part* DeSerializationSessionPrototype::deserializePartExternalData(Par...
function RigidBody (line 231) | RigidBody DeSerializationSessionPrototype::deserializeRigidBodyWithCon...
function PhysicalConstraint (line 257) | PhysicalConstraint DeSerializationSessionPrototype::deserializeConstra...
function serializeHardPhysicalConnection (line 268) | static void serializeHardPhysicalConnection(const HardPhysicalConnecti...
function HardPhysicalConnection (line 275) | static HardPhysicalConnection deserializeHardPhysicalConnection(std::i...
function MotorizedPhysical (line 315) | MotorizedPhysical* DeSerializationSessionPrototype::deserializeMotoriz...
function serializeVersion (line 357) | static void serializeVersion(std::ostream& ostream) {
function assertVersionCorrect (line 361) | static void assertVersionCorrect(std::istream& istream) {
FILE: Physics3D/misc/serialization/serialization.h
function namespace (line 32) | namespace P3D {
FILE: Physics3D/misc/serialization/serializeBasicTypes.cpp
type P3D (line 5) | namespace P3D {
function serializeBasicTypes (line 6) | void serializeBasicTypes(const char* data, size_t size, std::ostream& ...
function deserializeBasicTypes (line 10) | void deserializeBasicTypes(char* buf, size_t size, std::istream& istre...
function serializeString (line 32) | void serializeString(const std::string& str, std::ostream& ostream) {
function deserializeString (line 37) | std::string deserializeString(std::istream& istream) {
FILE: Physics3D/misc/serialization/serializeBasicTypes.h
function namespace (line 8) | namespace P3D {
FILE: Physics3D/misc/serialization/sharedObjectSerializer.h
function namespace (line 10) | namespace P3D {
function T (line 92) | T deserializeObject(std::istream& istream) const {
function removeObject (line 115) | void removeObject(const T& object) {
FILE: Physics3D/misc/toString.h
function namespace (line 20) | namespace P3D {
FILE: Physics3D/misc/unreachable.h
function namespace (line 3) | namespace P3D {
FILE: Physics3D/misc/validityHelper.cpp
type P3D (line 15) | namespace P3D {
function isValidTriangle (line 16) | bool isValidTriangle(Triangle t, int vertexCount) {
function isComplete (line 24) | static bool isComplete(const TriangleMesh& mesh) {
function isValid (line 74) | bool isValid(const TriangleMesh& mesh) {
function isValid (line 105) | bool isValid(const Polyhedron& poly) {
function isValid (line 123) | bool isValid(const IndexedShape& shape) {
function isPhysicalValid (line 154) | static bool isPhysicalValid(const Physical* phys, const MotorizedPhysi...
function isConnectedPhysicalValid (line 173) | static bool isConnectedPhysicalValid(const ConnectedPhysical* phys, co...
function isMotorizedPhysicalValid (line 177) | bool isMotorizedPhysicalValid(const MotorizedPhysical* mainPhys) {
FILE: Physics3D/misc/validityHelper.h
function namespace (line 12) | namespace P3D {
function isTranslationalMotionValid (line 125) | inline bool isTranslationalMotionValid(const TranslationalMotion& motion) {
function isRotationalMotionValid (line 128) | inline bool isRotationalMotionValid(const RotationalMotion& motion) {
function isMotionValid (line 131) | inline bool isMotionValid(const Motion& motion) {
type Triangle (line 135) | struct Triangle
type IndexedShape (line 138) | struct IndexedShape
FILE: Physics3D/motion.h
function namespace (line 8) | namespace P3D {
function getAngularAcceleration (line 59) | struct RotationalMotion {
function Vec3 (line 73) | inline Vec3 getAccelerationOfPoint(Vec3 relativePoint) const {
function TranslationalMotion (line 77) | inline TranslationalMotion getTranslationalMotionOfPoint(Vec3 relativePo...
function Vec3 (line 81) | inline Vec3 getRotationAfterDeltaT(double deltaT) const {
type Movement (line 93) | struct Movement {
function getAccelerationOfPoint (line 97) | struct Motion {
function TranslationalMotion (line 128) | inline TranslationalMotion getTranslationalMotionOfPoint(Vec3 relativePo...
function Motion (line 132) | inline Motion getMotionOfPoint(Vec3 relativePoint) const {
function Motion (line 139) | inline Motion addRelativeMotion(const Motion& relativeMotion) const {
function Motion (line 148) | inline Motion addOffsetRelativeMotion(Vec3 offset, const Motion& relativ...
function Movement (line 152) | inline Movement getMovementAfterDeltaT(double deltaT) const {
function TranslationalMotion (line 170) | inline TranslationalMotion localToGlobal(const Rotation& rot, const Tran...
function TranslationalMotion (line 173) | inline TranslationalMotion globalToLocal(const Rotation& rot, const Tran...
function RotationalMotion (line 176) | inline RotationalMotion localToGlobal(const Rotation& rot, const Rotatio...
function RotationalMotion (line 179) | inline RotationalMotion globalToLocal(const Rotation& rot, const Rotatio...
function Motion (line 183) | inline Motion localToGlobal(const Rotation& rot, const Motion& motion) {
function Motion (line 188) | inline Motion globalToLocal(const Rotation& rot, const Motion& motion) {
FILE: Physics3D/part.cpp
type P3D (line 16) | namespace P3D {
function recalculate (line 18) | void recalculate(Part* part) {
function recalculateAndUpdateParent (line 22) | void recalculateAndUpdateParent(Part* part, const Bounds& oldBounds) {
function Part (line 60) | Part& Part::operator=(Part&& other) noexcept {
function WorldPrototype (line 77) | WorldPrototype* Part::getWorld() {
function PartIntersection (line 98) | PartIntersection Part::intersects(const Part& other) const {
function BoundingBox (line 114) | BoundingBox Part::getLocalBounds() const {
function Vec3 (line 151) | Vec3 Part::getVelocity() const {
function Vec3 (line 154) | Vec3 Part::getAngularVelocity() const {
function Motion (line 157) | Motion Part::getMotion() const {
function Shape (line 185) | const Shape& Part::getShape() const {
function Vec3 (line 243) | Vec3 Part::getConveyorEffect() {
function mergePartLayers (line 290) | static void mergePartLayers(Part* first, Part* second, const std::vect...
function updateGroupBounds (line 301) | static void updateGroupBounds(std::vector<FoundLayerRepresentative>& l...
function getAllPartsInPhysical (line 307) | static std::vector<Part*> getAllPartsInPhysical(Part* rep) {
function addAllToGroupLayer (line 320) | static void addAllToGroupLayer(Part* layerOwner, const std::vector<Par...
function mergeLayersAround (line 328) | static void mergeLayersAround(Part* first, Part* second, PhysicalMerge...
function Physical (line 386) | Physical* Part::getPhysical() const {
function MotorizedPhysical (line 396) | MotorizedPhysical* Part::getMainPhysical() const {
function Physical (line 400) | Physical* Part::ensureHasPhysical() {
function CFrame (line 410) | CFrame& Part::getAttachToMainPart() const {
function CFrame (line 415) | CFrame Part::transformCFrameToParent(const CFrame& cframeRelativeToPar...
FILE: Physics3D/part.h
function namespace (line 5) | namespace P3D {
function namespace (line 23) | namespace P3D {
FILE: Physics3D/physical.cpp
type P3D (line 22) | namespace P3D {
function Physical (line 47) | Physical& Physical::operator=(Physical&& other) noexcept {
function liesInVector (line 105) | static inline bool liesInVector(const std::vector<T>& vec, const T* pt...
function RelativeMotion (line 202) | RelativeMotion ConnectedPhysical::getRelativeMotionBetweenParentAndSel...
function MotorizedPhysical (line 211) | MotorizedPhysical* Physical::makeMainPhysical() {
function removePhysicalFromList (line 235) | static void removePhysicalFromList(std::vector<MotorizedPhysical*>& ph...
function Physical (line 286) | static Physical* findPhysicalParent(Physical* findIn, const ConnectedP...
function computeInternalRelativeMotionTree (line 382) | static void computeInternalRelativeMotionTree(MonotonicTreeBuilder<Rel...
function InternalMotionTree (line 399) | InternalMotionTree MotorizedPhysical::getInternalRelativeMotionTree(Un...
function COMMotionTree (line 427) | COMMotionTree MotorizedPhysical::getCOMMotionTree(UnmanagedArray<Monot...
function WorldPrototype (line 756) | WorldPrototype* Physical::getWorld() const {
function CFrame (line 770) | CFrame Physical::getRelativeCFrameToMain() const {
function Vec3 (line 773) | Vec3 Physical::localToMain(const Vec3Local& vec) const {
function Vec3 (line 777) | Vec3 Physical::localToMainCOMRelative(const Vec3Local& vec) const {
function Vec3 (line 786) | Vec3 MotorizedPhysical::getVelocityOfCenterOfMass() const {
function SymmetricMat3 (line 795) | SymmetricMat3 MotorizedPhysical::getResponseMatrix(const Vec3Local& r)...
function Mat3 (line 803) | Mat3 MotorizedPhysical::getResponseMatrix(const Vec3Local& actionPoint...
function CFrame (line 830) | CFrame ConnectedPhysical::getRelativeCFrameToParent() const {
function Position (line 834) | Position MotorizedPhysical::getCenterOfMass() const {
function GlobalCFrame (line 838) | GlobalCFrame MotorizedPhysical::getCenterOfMassCFrame() const {
function Vec3 (line 842) | Vec3 MotorizedPhysical::getTotalImpulse() const {
function Vec3 (line 846) | Vec3 MotorizedPhysical::getTotalAngularMomentum() const {
function Motion (line 860) | Motion Physical::getMotion() const {
function Motion (line 868) | Motion MotorizedPhysical::getMotion() const {
function Motion (line 876) | Motion ConnectedPhysical::getMotion() const {
function Motion (line 890) | Motion Physical::getMotionOfCenterOfMass() const {
function Motion (line 893) | Motion MotorizedPhysical::getMotionOfCenterOfMass() const {
function Motion (line 896) | Motion ConnectedPhysical::getMotionOfCenterOfMass() const {
function COMMotionTree (line 940) | COMMotionTree InternalMotionTree::normalizeCenterOfMass() && {
function SymmetricMat3 (line 951) | SymmetricMat3 COMMotionTree::getInertia() const {
function Motion (line 969) | Motion COMMotionTree::getMotion() const {
function Vec3 (line 976) | Vec3 COMMotionTree::getInternalAngularMomentum() const {
function findAllLayersIn (line 1033) | std::vector<FoundLayerRepresentative> findAllLayersIn(MotorizedPhysica...
function findAllLayersIn (line 1048) | std::vector<FoundLayerRepresentative> findAllLayersIn(Part* part) {
FILE: Physics3D/physical.h
function namespace (line 21) | namespace P3D {
function class (line 475) | class InternalMotionTree {
function class (line 499) | class COMMotionTree {
function MonotonicTreeNode (line 539) | inline MonotonicTreeNode<RelativeMotion>* getPtrToFree() {
type FoundLayerRepresentative (line 561) | struct FoundLayerRepresentative {
FILE: Physics3D/relativeMotion.h
function namespace (line 6) | namespace P3D {
FILE: Physics3D/rigidBody.cpp
type P3D (line 9) | namespace P3D {
function AttachedPart (line 50) | const AttachedPart& RigidBody::getAttachFor(const Part* attachedPart) ...
function AttachedPart (line 60) | AttachedPart& RigidBody::getAttachFor(const Part* attachedPart) {
function liesInVector (line 71) | static inline bool liesInVector(const std::vector<T>& vec, const T* pt...
function CFrame (line 76) | CFrame RigidBody::makeMainPart(AttachedPart& newMainPart) {
FILE: Physics3D/rigidBody.h
function namespace (line 7) | namespace P3D {
type ConstPartIter (line 43) | struct ConstPartIter {
function IteratorEnd (line 64) | inline bool operator!=(IteratorEnd) const {
function IteratorEnd (line 68) | inline bool operator==(IteratorEnd) const {
function class (line 73) | class RigidBody {
FILE: Physics3D/softlinks/alignmentLink.cpp
type P3D (line 3) | namespace P3D {
function Vec3 (line 16) | Vec3 AlignmentLink::getGlobalMoment() noexcept {
FILE: Physics3D/softlinks/alignmentLink.h
function namespace (line 5) | namespace P3D {
FILE: Physics3D/softlinks/elasticLink.cpp
type P3D (line 3) | namespace P3D {
FILE: Physics3D/softlinks/elasticLink.h
function namespace (line 7) | namespace P3D {
FILE: Physics3D/softlinks/magneticLink.cpp
type P3D (line 3) | namespace P3D {
function Vec3 (line 15) | Vec3 MagneticLink::forceAppliedToTheLink() noexcept {
FILE: Physics3D/softlinks/magneticLink.h
function namespace (line 5) | namespace P3D {
FILE: Physics3D/softlinks/softLink.cpp
type P3D (line 3) | namespace P3D {
function GlobalCFrame (line 11) | GlobalCFrame SoftLink::getGlobalCFrameOfAttachmentA() const {
function GlobalCFrame (line 15) | GlobalCFrame SoftLink::getGlobalCFrameOfAttachmentB() const {
function CFrame (line 19) | CFrame SoftLink::getLocalCFrameOfAttachmentA() const {
function CFrame (line 23) | CFrame SoftLink::getLocalCFrameOfAttachmentB() const {
function CFrame (line 27) | CFrame SoftLink::getRelativeOfAttachmentA() const {
function CFrame (line 31) | CFrame SoftLink::getRelativeOfAttachmentB() const {
function Position (line 35) | Position SoftLink::getGlobalPositionOfAttachmentB() const {
function Position (line 38) | Position SoftLink::getGlobalPositionOfAttachmentA() const {
function Vec3 (line 41) | Vec3 SoftLink::getLocalPositionOfAttachmentA() const {
function Vec3 (line 44) | Vec3 SoftLink::getLocalPositionOfAttachmentB() const {
function Vec3 (line 47) | Vec3 SoftLink::getRelativePositionOfAttachmentA() const {
function Vec3 (line 50) | Vec3 SoftLink::getRelativePositionOfAttachmentB() const {
FILE: Physics3D/softlinks/softLink.h
function namespace (line 7) | namespace P3D {
FILE: Physics3D/softlinks/springLink.cpp
type P3D (line 3) | namespace P3D {
function Vec3 (line 16) | Vec3 SpringLink::forceAppliedToTheLink() noexcept {
FILE: Physics3D/softlinks/springLink.h
function namespace (line 5) | namespace P3D {
FILE: Physics3D/threading/physicsThread.cpp
type P3D (line 8) | namespace P3D {
function emptyFunc (line 11) | static void emptyFunc(WorldPrototype*) {}
FILE: Physics3D/threading/physicsThread.h
function namespace (line 9) | namespace P3D {
FILE: Physics3D/threading/sharedLockGuard.h
function namespace (line 5) | namespace P3D {
function upgrade (line 23) | inline void upgrade() {
function downgrade (line 32) | inline void downgrade() {
function class (line 42) | class UnlockOnDestroy {
function class (line 51) | class UnlockSharedOnDestroy {
FILE: Physics3D/threading/threadPool.h
function namespace (line 9) | namespace P3D {
FILE: Physics3D/threading/upgradeableMutex.cpp
type P3D (line 6) | namespace P3D {
FILE: Physics3D/threading/upgradeableMutex.h
function namespace (line 6) | namespace P3D {
FILE: Physics3D/world.cpp
type P3D (line 10) | namespace P3D {
function pairLayers (line 79) | static std::pair<int, int> pairLayers(int layer1, int layer2) {
function createNodeFor (line 135) | static void createNodeFor(P3D::BoundsTree<Part>& tree, MotorizedPhysic...
function createNewNodeFor (line 180) | static void createNewNodeFor(MotorizedPhysical* motorPhys, BoundsTree<...
function assignLayersForPhysicalRecurse (line 278) | static void assignLayersForPhysicalRecurse(const Physical& phys, std::...
FILE: Physics3D/world.h
function namespace (line 14) | namespace P3D {
FILE: Physics3D/worldIteration.h
function namespace (line 6) | namespace P3D {
FILE: Physics3D/worldPhysics.cpp
type P3D (line 19) | namespace P3D {
function handleCollision (line 24) | void handleCollision(Part& part1, Part& part2, Position collisionPoint...
function handleTerrainCollision (line 110) | void handleTerrainCollision(Part& part1, Part& part2, Position collisi...
function tickWorldUnsynchronized (line 193) | void tickWorldUnsynchronized(WorldPrototype& world, ThreadPool& thread...
function tickWorldSynchronized (line 213) | void tickWorldSynchronized(WorldPrototype& world, ThreadPool& threadPo...
function applyExternalForces (line 242) | void applyExternalForces(WorldPrototype& world) {
function PartIntersection (line 248) | PartIntersection safeIntersects(const Part& p1, const Part& p2) {
function refineColissions (line 270) | void refineColissions(std::vector<Colission>& colissions) {
function parallelRefineColissions (line 298) | void parallelRefineColissions(ThreadPool& threadPool, std::vector<Coli...
function findColissions (line 347) | void findColissions(WorldPrototype& world, ColissionBuffer& curColissi...
function findColissionsParallel (line 364) | void findColissionsParallel(WorldPrototype& world, ColissionBuffer& cu...
function handleColissions (line 381) | void handleColissions(ColissionBuffer& curColissions) {
function handleConstraints (line 390) | void handleConstraints(WorldPrototype& world) {
function update (line 395) | void update(WorldPrototype& world) {
FILE: Physics3D/worldPhysics.h
function namespace (line 11) | namespace P3D {
FILE: application/application.cpp
type P3D::Application (line 63) | namespace P3D::Application {
function init (line 77) | void init(const ::Util::ParsedArgs& cmdArgs) {
function setupGL (line 118) | void setupGL() {
function setupWorld (line 138) | void setupWorld(const ::Util::ParsedArgs& cmdArgs) {
function setupDebug (line 276) | void setupDebug() {
function loadFile (line 280) | void loadFile(const char* file) {
function onFileDrop (line 294) | bool onFileDrop(Engine::WindowDropEvent& event) {
function onKeyPress (line 300) | bool onKeyPress(Engine::KeyPressEvent& keyEvent) {
function onEvent (line 327) | void onEvent(Engine::Event& event) {
function stop (line 337) | void stop(int returnCode) {
function togglePause (line 350) | void togglePause() {
function pause (line 354) | void pause() {
function unpause (line 358) | void unpause() {
function isPaused (line 362) | bool isPaused() {
function setSpeed (line 366) | void setSpeed(double newSpeed) {
function getSpeed (line 370) | double getSpeed() {
function runTick (line 374) | void runTick() {
function toggleFlying (line 378) | void toggleFlying() {
function main (line 396) | int main(int argc, const char** args) {
FILE: application/application.h
function namespace (line 5) | namespace P3D::Engine {
function namespace (line 9) | namespace P3D::Application {
FILE: application/builtinWorlds.cpp
type P3D::Application (line 27) | namespace P3D::Application {
function buildBenchmarkWorld (line 31) | void buildBenchmarkWorld(PlayerWorld& world) {
function buildShowcaseWorld (line 44) | void buildShowcaseWorld(Screen& screen, PlayerWorld& world) {
function buildDebugWorld (line 399) | void buildDebugWorld(Screen& screen, PlayerWorld& world) {
function buildFloorWorld (line 419) | void buildFloorWorld(Screen& screen, PlayerWorld& world) {
function buildBallWorld (line 431) | void buildBallWorld(Screen& screen, PlayerWorld& world) {
function buildBoxWorld (line 451) | void buildBoxWorld(Screen& screen, PlayerWorld& world) {
FILE: application/builtinWorlds.h
function namespace (line 6) | namespace P3D::Application {
FILE: application/ecs/components.h
function namespace (line 18) | namespace P3D::Application {
function RC (line 437) | struct Name : RC {
function RC (line 448) | struct Collider : RC {
function RC (line 458) | struct Light : public RC {
function RC (line 475) | struct Attachment : public RC {
function RC (line 500) | struct SoftLink : public RC {
function SoftLink (line 522) | struct MagneticLink : public SoftLink {
function SoftLink (line 526) | struct SpringLink : public SoftLink {
function SoftLink (line 530) | struct ElasticLink : public SoftLink {
function SoftLink (line 534) | struct AlignmentLink : public SoftLink {
function RC (line 538) | struct HardConstraint : public RC {
function HardConstraint (line 552) | struct FixedConstraint : public HardConstraint {
FILE: application/ecs/entityBuilder.h
function namespace (line 8) | namespace P3D::Application {
FILE: application/eventHandler.cpp
type P3D::Application (line 8) | namespace P3D::Application {
FILE: application/eventHandler.h
function namespace (line 3) | namespace P3D::Application {
FILE: application/extendedPart.cpp
type P3D::Application (line 11) | namespace P3D::Application {
FILE: application/extendedPart.h
function namespace (line 8) | namespace P3D::Application {
FILE: application/input/playerController.cpp
type P3D::Application (line 19) | namespace P3D::Application {
FILE: application/input/playerController.h
function namespace (line 5) | namespace P3D::Application {
FILE: application/input/standardInputHandler.cpp
type P3D::Application (line 29) | namespace P3D::Application {
function KEY_BIND (line 90) | KEY_BIND(KeyboardOptions::Tick::Speed::up) {
function KEY_BIND (line 95) | KEY_BIND(KeyboardOptions::Tick::Speed::down) {
function KEY_BIND (line 100) | KEY_BIND(KeyboardOptions::Tick::run) {
function KEY_BIND (line 104) | KEY_BIND(Keyboard::KEY_O) {
function KEY_BIND (line 121) | KEY_BIND(KeyboardOptions::Tick::pause) {
function KEY_BIND (line 125) | KEY_BIND(KeyboardOptions::Part::remove) {
function KEY_BIND (line 134) | KEY_BIND(KeyboardOptions::Debug::pies) {
function KEY_BIND (line 138) | KEY_BIND(KeyboardOptions::Part::makeMainPart) {
function KEY_BIND (line 143) | KEY_BIND(KeyboardOptions::Part::makeMainPhysical) {
function KEY_BIND (line 159) | KEY_BIND(KeyboardOptions::World::valid) {
function KEY_BIND (line 169) | KEY_BIND(KeyboardOptions::Edit::rotate) {
function KEY_BIND (line 173) | KEY_BIND(KeyboardOptions::Edit::translate) {
function KEY_BIND (line 177) | KEY_BIND(KeyboardOptions::Edit::scale) {
function KEY_BIND (line 181) | KEY_BIND(KeyboardOptions::Edit::select) {
function KEY_BIND (line 185) | KEY_BIND(KeyboardOptions::Edit::region) {
function KEY_BIND (line 189) | KEY_BIND(KeyboardOptions::Debug::spheres) {
function KEY_BIND (line 193) | KEY_BIND(KeyboardOptions::Debug::tree) {
function KEY_BIND (line 201) | KEY_BIND(KeyboardOptions::Application::close) {
function KEY_RANGE (line 207) | KEY_RANGE(Keyboard::KEY_F1, Keyboard::KEY_F9) {
function KEY_RANGE (line 211) | KEY_RANGE(Keyboard::KEY_NUMBER_1, Keyboard::KEY_NUMBER_3) {
function KEY_BIND (line 223) | KEY_BIND(KeyboardOptions::Move::fly) {
FILE: application/input/standardInputHandler.h
function namespace (line 7) | namespace P3D::Application {
FILE: application/io/saveDialog.cpp
type P3D::Application (line 9) | namespace P3D::Application {
function saveWorldDialog (line 13) | bool saveWorldDialog(char* worldFilePath) {
function openWorldDialog (line 31) | bool openWorldDialog(char* worldFilePath) {
function stripFinalNewlines (line 50) | static void stripFinalNewlines(char* fileName) {
function saveWorldDialog (line 57) | bool saveWorldDialog(char* worldFilePath) {
function openWorldDialog (line 77) | bool openWorldDialog(char* worldFilePath) {
FILE: application/io/saveDialog.h
function namespace (line 3) | namespace P3D::Application {
FILE: application/io/serialization.cpp
type P3D::Application (line 22) | namespace P3D::Application {
function serializeMaterial (line 30) | static void serializeMaterial(const Graphics::Comp::Material& material...
function deserializeMaterial (line 45) | static Graphics::Comp::Material deserializeMaterial(std::istream& istr...
class Serializer (line 72) | class Serializer : public SerializationSession<ExtendedPart> {
method serializePartExternalData (line 75) | virtual void serializePartExternalData(const ExtendedPart& part, std...
class Deserializer (line 82) | class Deserializer : public DeSerializationSession<ExtendedPart> {
method ExtendedPart (line 85) | virtual ExtendedPart* deserializeExtendedPart(Part&& partPhysicalDat...
function openWriteFile (line 95) | static void openWriteFile(std::ofstream& fstream, const char* fileName) {
function openReadFile (line 104) | static void openReadFile(std::ifstream& fstream, const char* fileName) {
FILE: application/io/serialization.h
function namespace (line 9) | namespace P3D::Application {
FILE: application/layer/cameraLayer.cpp
type P3D::Application (line 9) | namespace P3D::Application {
FILE: application/layer/cameraLayer.h
function namespace (line 6) | namespace P3D::Application {
FILE: application/layer/constraintLayer.cpp
type P3D::Application (line 21) | namespace P3D::Application {
function renderObject (line 31) | static void renderObject(const Graphics::Comp::Mesh& shape, const Glob...
function renderConstraintLineBetween (line 38) | static void renderConstraintLineBetween(Position p1, Position p2) {
function renderBar (line 61) | static void renderBar(GlobalCFrame cframe, Vec3 delta, float thickness...
function renderPiston (line 70) | static void renderPiston(const SinusoidalPistonConstraint* piston, con...
function renderMotor (line 93) | static void renderMotor(const ConstantSpeedMotorConstraint* motor, con...
function renderBallConstraint (line 98) | static void renderBallConstraint(const GlobalCFrame& cframeA, const Gl...
function renderHingeConstraint (line 106) | static void renderHingeConstraint(const GlobalCFrame& cframeA, const G...
function renderBarConstraint (line 116) | static void renderBarConstraint(const GlobalCFrame& cframeA, const Glo...
function renderHardConstraint (line 139) | static void renderHardConstraint( const ConnectedPhysical& conPhys) {
function recurseRenderHardConstraints (line 159) | static void recurseRenderHardConstraints(const Physical& physical) {
function renderConstraint (line 166) | static void renderConstraint(const PhysicalConstraint& constraint) {
function renderSpringLink (line 179) | static void renderSpringLink(const GlobalCFrame& start) {
FILE: application/layer/constraintLayer.h
function namespace (line 5) | namespace P3D::Application {
FILE: application/layer/debugLayer.cpp
type P3D::Application (line 25) | namespace P3D::Application {
function renderSphere (line 36) | void renderSphere(double radius, const Position& position, const Color...
function renderBox (line 43) | void renderBox(const GlobalCFrame& cframe, double width, double height...
function renderBounds (line 50) | void renderBounds(const Bounds& bounds, const Color& color) {
function Color (line 56) | static Color getCyclingColor(int depth) {
function renderBoundsForDepth (line 62) | static void renderBoundsForDepth(const Bounds& bounds, int depth) {
function recursiveRenderColTree (line 66) | static void recursiveRenderColTree(const P3D::TreeTrunk& curTrunk, int...
function recursiveColTreeForOneObject (line 78) | static bool recursiveColTreeForOneObject(const TreeTrunk& curTrunk, in...
function renderTree (line 96) | static void renderTree(const BoundsTree<Part>& tree) {
function renderTreeForOneObject (line 100) | static void renderTreeForOneObject(const BoundsTree<Part>& tree, const...
FILE: application/layer/debugLayer.h
function namespace (line 5) | namespace P3D::Graphics {
function namespace (line 13) | namespace P3D::Application {
FILE: application/layer/debugOverlay.cpp
type P3D::Application (line 24) | namespace P3D::Application {
FILE: application/layer/debugOverlay.h
function namespace (line 5) | namespace P3D::Application {
FILE: application/layer/guiLayer.cpp
type P3D::Application (line 14) | namespace P3D::Application {
function onMouseMove (line 16) | bool onMouseMove(const Engine::MouseMoveEvent& event) {
function onMousePress (line 22) | bool onMousePress(const Engine::MousePressEvent& event) {
function onMouseRelease (line 28) | bool onMouseRelease(const Engine::MouseReleaseEvent& event) {
function onMouseDrag (line 34) | bool onMouseDrag(const Engine::MouseDragEvent& event) {
function onWindowResize (line 40) | bool onWindowResize(const Engine::WindowResizeEvent& event) {
FILE: application/layer/guiLayer.h
function namespace (line 5) | namespace P3D::Application {
FILE: application/layer/imguiLayer.cpp
type P3D::Application (line 21) | namespace P3D::Application {
FILE: application/layer/imguiLayer.h
function namespace (line 5) | namespace P3D::Application {
FILE: application/layer/modelLayer.cpp
type P3D::Application (line 32) | namespace P3D::Application {
type RelationToSelectedPart (line 34) | enum class RelationToSelectedPart {
function RelationToSelectedPart (line 43) | static RelationToSelectedPart getRelationToSelectedPart(const Part* se...
function Color (line 71) | static Color getAmbientForPartForSelected(Screen* screen, Part* part) {
function Color (line 90) | static Color getAlbedoForPart(Screen* screen, ExtendedPart* part) {
type EntityInfo (line 168) | struct EntityInfo {
FILE: application/layer/modelLayer.h
function namespace (line 6) | namespace P3D::Application {
FILE: application/layer/pickerLayer.cpp
type P3D::Application (line 29) | namespace P3D::Application {
FILE: application/layer/pickerLayer.h
function namespace (line 6) | namespace P3D::Application {
FILE: application/layer/postprocessLayer.cpp
type P3D::Application (line 13) | namespace P3D::Application {
FILE: application/layer/postprocessLayer.h
function namespace (line 5) | namespace P3D::Application {
FILE: application/layer/shadowLayer.cpp
type P3D::Application (line 23) | namespace P3D::Application {
FILE: application/layer/shadowLayer.h
function namespace (line 5) | namespace P3D::Application {
FILE: application/layer/skyboxLayer.cpp
type P3D::Application (line 17) | namespace P3D::Application {
function getScroll (line 33) | float getScroll(const Screen* screen) {
function updateMist (line 40) | void updateMist(float time) {
function updateStars (line 50) | void updateStars(float time) {
FILE: application/layer/skyboxLayer.h
function namespace (line 7) | namespace P3D {
function namespace (line 13) | namespace P3D::Application {
FILE: application/layer/testLayer.cpp
type P3D::Application (line 9) | namespace P3D::Application {
FILE: application/layer/testLayer.h
function namespace (line 5) | namespace P3D::Application {
FILE: application/legacy/frames.h
function namespace (line 25) | namespace Application {
type DebugFrame (line 192) | struct DebugFrame
function init (line 237) | void init() override {
function update (line 273) | void update() override {
type PropertiesFrame (line 298) | struct PropertiesFrame
function init (line 356) | void init() override {
function update (line 439) | void update() override {
FILE: application/picker/ray.cpp
type P3D::Application (line 6) | namespace P3D::Application {
function Vec2f (line 8) | Vec2f getNormalizedDeviceSpacePosition(const Vec2f& viewportSpacePosit...
function Vec3f (line 14) | Vec3f calcRay(const Screen& screen, Vec2f mouse) {
function Ray (line 25) | Ray getMouseRay(const Screen& screen, const Vec2f& mouse) {
FILE: application/picker/ray.h
function namespace (line 5) | namespace P3D::Application {
FILE: application/picker/selection.cpp
type P3D::Application (line 8) | namespace P3D::Application {
FILE: application/picker/selection.h
function namespace (line 8) | namespace P3D::Application {
FILE: application/picker/tools/alignmentLinkTool.cpp
type P3D::Application (line 10) | namespace P3D::Application {
FILE: application/picker/tools/alignmentLinkTool.h
function namespace (line 6) | namespace P3D::Application {
FILE: application/picker/tools/attachmentTool.cpp
type P3D::Application (line 10) | namespace P3D::Application {
FILE: application/picker/tools/attachmentTool.h
function namespace (line 5) | namespace P3D::Application {
FILE: application/picker/tools/elasticLinkTool.cpp
type P3D::Application (line 11) | namespace P3D::Application {
FILE: application/picker/tools/elasticLinkTool.h
function namespace (line 6) | namespace P3D::Application {
FILE: application/picker/tools/fixedConstraintTool.cpp
type P3D::Application (line 11) | namespace P3D::Application {
FILE: application/picker/tools/fixedConstraintTool.h
function namespace (line 6) | namespace P3D::Application {
FILE: application/picker/tools/magneticLinkTool.cpp
type P3D::Application (line 11) | namespace P3D::Application {
FILE: application/picker/tools/magneticLinkTool.h
function namespace (line 6) | namespace P3D::Application {
FILE: application/picker/tools/motorConstraintTool.cpp
type P3D::Application (line 13) | namespace P3D::Application {
FILE: application/picker/tools/motorConstraintTool.h
function namespace (line 6) | namespace P3D::Application {
FILE: application/picker/tools/pathTool.cpp
type P3D::Application (line 13) | namespace P3D::Application {
function Vec3 (line 78) | Vec3 intersect(double distance) {
FILE: application/picker/tools/pathTool.h
function namespace (line 6) | namespace P3D::Application {
FILE: application/picker/tools/pistonConstraintTool.cpp
type P3D::Application (line 12) | namespace P3D::Application {
FILE: application/picker/tools/pistonConstraintTool.h
function namespace (line 6) | namespace P3D::Application {
FILE: application/picker/tools/regionSelectionTool.cpp
type P3D::Application (line 23) | namespace P3D::Application {
FILE: application/picker/tools/regionSelectionTool.h
type ExtendedPart (line 9) | struct ExtendedPart
function namespace (line 11) | namespace P3D::Application {
FILE: application/picker/tools/rotationTool.cpp
type P3D::Application (line 24) | namespace P3D::Application {
FILE: application/picker/tools/rotationTool.h
function namespace (line 8) | namespace P3D::Application {
FILE: application/picker/tools/scaleTool.cpp
type P3D::Application (line 24) | namespace P3D::Application {
function Polyhedron (line 51) | static Polyhedron createBoxOnStick(float boxSide, float stickRadius) {
FILE: application/picker/tools/scaleTool.h
function namespace (line 8) | namespace P3D::Application {
FILE: application/picker/tools/selectionTool.cpp
type P3D::Graphics (line 22) | namespace P3D::Graphics {
class TextureResource (line 23) | class TextureResource
type P3D::Application (line 26) | namespace P3D::Application {
FILE: application/picker/tools/selectionTool.h
type ExtendedPart (line 13) | struct ExtendedPart
function namespace (line 15) | namespace P3D::Application {
FILE: application/picker/tools/springLinkTool.cpp
type P3D::Application (line 11) | namespace P3D::Application {
FILE: application/picker/tools/springLinkTool.h
function namespace (line 6) | namespace P3D::Application {
FILE: application/picker/tools/toolSpacing.h
function namespace (line 5) | namespace P3D::Application {
FILE: application/picker/tools/translationTool.cpp
type P3D::Application (line 25) | namespace P3D::Application {
function Polyhedron (line 58) | static Polyhedron createArrow(float arrowHeadLength, float arrowHeadRa...
FILE: application/picker/tools/translationTool.h
function namespace (line 9) | namespace P3D::Application {
FILE: application/resources.h
type ResourceDescriptor (line 3) | struct ResourceDescriptor
FILE: application/shader/basicShader.cpp
type P3D::Application (line 8) | namespace P3D::Application {
FILE: application/shader/basicShader.h
function namespace (line 6) | namespace P3D::Graphics::Comp {
function namespace (line 10) | namespace P3D::Application {
FILE: application/shader/shaderBase.cpp
type P3D::Application (line 8) | namespace P3D::Application {
FILE: application/shader/shaderBase.h
function namespace (line 9) | namespace P3D::Application {
FILE: application/shader/shaders.cpp
type P3D::Application (line 12) | namespace P3D::Application {
type Shaders (line 14) | namespace Shaders {
function onInit (line 33) | void onInit() {
function onClose (line 71) | void onClose() {
FILE: application/shader/shaders.h
function namespace (line 10) | namespace P3D::Graphics {
function namespace (line 16) | namespace P3D::Application {
FILE: application/view/camera.cpp
type P3D::Application (line 18) | namespace P3D::Application {
function Mat4f (line 52) | Mat4f Camera::getViewRotation() {
FILE: application/view/camera.h
function namespace (line 6) | namespace P3D::Engine {
function namespace (line 13) | namespace P3D::Application {
FILE: application/view/debugFrame.cpp
type P3D::Application (line 9) | namespace P3D::Application {
FILE: application/view/debugFrame.h
function namespace (line 5) | namespace P3D::Application {
FILE: application/view/ecsFrame.cpp
type P3D::Application (line 31) | namespace P3D::Application {
function GLID (line 61) | static GLID getColliderIcon(IRef<Comp::Collider> collider) {
function GLID (line 80) | static GLID getMeshIcon(IRef<Graphics::Comp::Mesh> mesh) {
function HeaderNode (line 101) | static void HeaderNode() {
function IconTreeNode (line 145) | static bool IconTreeNode(ImU32 id, Engine::Registry64& registry, const...
function EntityTreeNode (line 279) | static bool EntityTreeNode(ImU32 id, Engine::Registry64& registry,
function ColliderMenuItem (line 305) | static bool ColliderMenuItem(const char* label, GLID icon, bool select...
function softLinkDispatch (line 507) | bool softLinkDispatch(Engine::Registry64& registry, const std::vector<...
function hardConstraintDispatch (line 539) | bool hardConstraintDispatch(Engine::Registry64& registry, const std::v...
function attachmentDispatch (line 570) | void attachmentDispatch(Engine::Registry64& registry, const std::vecto...
FILE: application/view/ecsFrame.h
function namespace (line 5) | namespace P3D {
function namespace (line 15) | namespace P3D::Application {
FILE: application/view/environmentFrame.cpp
type P3D::Application (line 12) | namespace P3D::Application {
FILE: application/view/environmentFrame.h
function namespace (line 6) | namespace P3D::Application {
FILE: application/view/frames.cpp
type P3D::Application (line 13) | namespace P3D::Application {
FILE: application/view/frames.h
function namespace (line 5) | namespace P3D::Application {
FILE: application/view/layerFrame.cpp
type P3D::Application (line 8) | namespace P3D::Application {
FILE: application/view/layerFrame.h
function namespace (line 5) | namespace P3D::Engine {
function namespace (line 9) | namespace P3D::Application {
FILE: application/view/propertiesFrame.cpp
type P3D::Application (line 19) | namespace P3D::Application {
function _ecs_property_frame_start (line 30) | bool _ecs_property_frame_start(Engine::Registry64& registry, Engine::R...
function _ecs_property_frame_start2 (line 51) | bool _ecs_property_frame_start2(Engine::Registry64& registry, Engine::...
function renderEntity (line 144) | void renderEntity(Engine::Registry64& registry, Engine::Registry64::en...
function renderEntity (line 150) | void renderEntity(Engine::Registry64& registry, Engine::Registry64::en...
function renderEntity (line 213) | void renderEntity(Engine::Registry64& registry, Engine::Registry64::en...
function renderEntity (line 221) | void renderEntity(Engine::Registry64& registry, Engine::Registry64::en...
function renderEntity (line 243) | void renderEntity(Engine::Registry64& registry, Engine::Registry64::en...
function renderEntity (line 310) | void renderEntity(Engine::Registry64& registry, Engine::Registry64::en...
function renderEntity (line 324) | void renderEntity(Engine::Registry64& registry, Engine::Registry64::en...
function renderEntity (line 383) | void renderEntity(Engine::Registry64& registry, Engine::Registry64::en...
function renderEntity (line 408) | void renderEntity(Engine::Registry64& registry, Engine::Registry64::en...
function renderSoftlink (line 456) | void renderSoftlink(Engine::Registry64& registry, Engine::Registry64::...
function renderEntity (line 507) | void renderEntity(Engine::Registry64& registry, Engine::Registry64::en...
function renderEntity (line 525) | void renderEntity(Engine::Registry64& registry, Engine::Registry64::en...
function renderEntity (line 541) | void renderEntity(Engine::Registry64& registry, Engine::Registry64::en...
function renderEntity (line 557) | void renderEntity(Engine::Registry64& registry, Engine::Registry64::en...
function renderEntity (line 567) | void renderEntity(Engine::Registry64& registry, Engine::Registry64::en...
FILE: application/view/propertiesFrame.h
function namespace (line 5) | namespace P3D::Application {
FILE: application/view/resourceFrame.cpp
type P3D::Application (line 14) | namespace P3D::Application {
function renderPropertyEditor (line 81) | void renderPropertyEditor(ShaderResource* shader, Property& property) {
FILE: application/view/resourceFrame.h
function namespace (line 5) | namespace P3D::Graphics {
function namespace (line 14) | namespace P3D::Application {
FILE: application/view/screen.cpp
type GLFWwindow (line 38) | struct GLFWwindow
type P3D::Application (line 40) | namespace P3D::Application {
function initGLFW (line 42) | bool initGLFW() {
function initGLEW (line 59) | bool initGLEW() {
function terminateGLFW (line 73) | void terminateGLFW() {
FILE: application/view/screen.h
function namespace (line 11) | namespace P3D {
function namespace (line 15) | namespace P3D::Graphics {
function namespace (line 22) | namespace P3D::Application {
FILE: application/view/toolbarFrame.cpp
type P3D::Application (line 13) | namespace P3D::Application {
FILE: application/view/toolbarFrame.h
function namespace (line 5) | namespace P3D::Application {
FILE: application/worldBuilder.cpp
type P3D::Application (line 22) | namespace P3D::Application {
type WorldBuilder (line 24) | namespace WorldBuilder {
function init (line 34) | void init() {
function createDominoAt (line 44) | void createDominoAt(const GlobalCFrame& cframe) {
function makeDominoStrip (line 49) | void makeDominoStrip(int dominoCount, Position dominoStart, Vec3 dom...
function makeDominoTower (line 55) | void makeDominoTower(int floors, int circumference, Position origin) {
function buildFloor (line 68) | void buildFloor(double width, double depth, int folder) {
function buildFloorAndWalls (line 73) | void buildFloorAndWalls(double width, double depth, double wallHeigh...
function HollowBoxParts (line 120) | HollowBoxParts buildHollowBox(Bounds box, double wallThickness) {
function getYOffset (line 142) | double getYOffset(double x, double z) {
function buildTree (line 153) | void buildTree(Position treePos, int treeFolder) {
function buildConveyor (line 175) | void buildConveyor(double width, double length, const GlobalCFrame& ...
function buildTrebuchet (line 188) | void buildTrebuchet(const GlobalCFrame& cframe, double baseWidth, do...
function produceAxes (line 221) | std::array<ExtendedPart*, 3> produceAxes(const GlobalCFrame& cf, con...
function attachAxes (line 231) | void attachAxes(ExtendedPart* part, double scale) {
function buildTerrain (line 241) | void buildTerrain(double width, double depth, int folder) {
function buildCar (line 291) | void buildCar(const GlobalCFrame& location, int folder) {
FILE: application/worldBuilder.h
function namespace (line 13) | namespace P3D::Application {
FILE: application/worlds.cpp
type P3D::Application (line 15) | namespace P3D::Application {
FILE: application/worlds.h
function namespace (line 7) | namespace P3D::Application {
FILE: benchmarks/basicWorld.cpp
type P3D (line 9) | namespace P3D {
class BasicWorldBenchmark (line 10) | class BasicWorldBenchmark : public WorldBenchmark {
method BasicWorldBenchmark (line 12) | BasicWorldBenchmark() : WorldBenchmark("basicWorld", 1000) {}
method init (line 14) | void init() {
FILE: benchmarks/benchmark.cpp
function Benchmark (line 19) | Benchmark* getBenchFor(std::string id) {
function split (line 33) | std::vector<std::string> split(std::string str, char splitChar) {
function runBenchmark (line 49) | static void runBenchmark(Benchmark* bench) {
function runBenchmarks (line 70) | static void runBenchmarks(const std::vector<std::string>& benchmarks) {
function main (line 87) | int main(int argc, const char** args) {
FILE: benchmarks/benchmark.h
function class (line 3) | class Benchmark {
FILE: benchmarks/complexObjectBenchmark.cpp
type P3D (line 8) | namespace P3D {
class ComplexObjectBenchmark (line 9) | class ComplexObjectBenchmark : public WorldBenchmark {
method ComplexObjectBenchmark (line 11) | ComplexObjectBenchmark() : WorldBenchmark("complexObject", 10000) {}
method init (line 13) | void init() {
FILE: benchmarks/ecsBenchmark.cpp
type P3D::Engine (line 5) | namespace P3D::Engine {
class ECSGetFromRegistryBenchmark (line 6) | class ECSGetFromRegistryBenchmark : public Benchmark {
method ECSGetFromRegistryBenchmark (line 8) | ECSGetFromRegistryBenchmark() : Benchmark("ecsGetFromRegistryBenchma...
type A (line 14) | struct A : public RC {
method A (line 17) | A(int i) : i(i) {}
method init (line 20) | void init() override {
method run (line 28) | void run() override {
method printResults (line 39) | void printResults(double timeTaken) override {
class ECSGetFromViewConjunctionBenchmark (line 45) | class ECSGetFromViewConjunctionBenchmark : public Benchmark {
method ECSGetFromViewConjunctionBenchmark (line 47) | ECSGetFromViewConjunctionBenchmark() : Benchmark("ecsGetFromViewConj...
type A (line 52) | struct A : public RC { int i; A(int i) : i(i) {} }
method A (line 52) | A(int i) : i(i) {}
method init (line 54) | void init() override {
method run (line 62) | void run() override {
method printResults (line 73) | void printResults(double timeTaken) override {
FILE: benchmarks/getBoundsPerformance.cpp
type P3D (line 7) | namespace P3D {
class GetBounds (line 8) | class GetBounds : public Benchmark {
method GetBounds (line 12) | GetBounds() : Benchmark("getBounds") {}
method init (line 14) | void init() override { this->poly = ShapeLibrary::createSphere(1.0, ...
method run (line 15) | void run() override {
FILE: benchmarks/manyCubesBenchmark.cpp
type P3D (line 9) | namespace P3D {
class ManyCubesBenchmark (line 10) | class ManyCubesBenchmark : public WorldBenchmark {
method ManyCubesBenchmark (line 12) | ManyCubesBenchmark() : WorldBenchmark("manyCubes", 10000) {}
method init (line 14) | void init() {
FILE: benchmarks/rotationBenchmark.cpp
type P3D (line 6) | namespace P3D {
function randomDouble (line 7) | static double randomDouble() {
class RotationLocalToGlobalVecCPU (line 13) | class RotationLocalToGlobalVecCPU : public Benchmark {
method RotationLocalToGlobalVecCPU (line 17) | RotationLocalToGlobalVecCPU() : Benchmark("rotationL2GVecCPU") {}
method init (line 19) | void init() override {
method run (line 23) | void run() override {
class RotationLocalToGlobalMatCPU (line 30) | class RotationLocalToGlobalMatCPU : public Benchmark {
method RotationLocalToGlobalMatCPU (line 34) | RotationLocalToGlobalMatCPU() : Benchmark("rotationL2GMatCPU") {}
method init (line 36) | void init() override {
method run (line 40) | void run() override {
class RotationLocalToGlobalRotCPU (line 47) | class RotationLocalToGlobalRotCPU : public Benchmark {
method RotationLocalToGlobalRotCPU (line 51) | RotationLocalToGlobalRotCPU() : Benchmark("rotationL2GRotCPU") {}
method init (line 53) | void init() override {
method run (line 57) | void run() override {
class RotationLocalToGlobalVecMem (line 66) | class RotationLocalToGlobalVecMem : public Benchmark {
method RotationLocalToGlobalVecMem (line 70) | RotationLocalToGlobalVecMem() : Benchmark("rotationL2GVecMem") {}
method init (line 72) | void init() override {
method run (line 82) | void run() override {
class RotationLocalToGlobalMatMem (line 89) | class RotationLocalToGlobalMatMem : public Benchmark {
method RotationLocalToGlobalMatMem (line 93) | RotationLocalToGlobalMatMem() : Benchmark("rotationL2GMatMem") {}
method init (line 95) | void init() override {
method run (line 105) | void run() override {
class RotationLocalToGlobalRotMem (line 112) | class RotationLocalToGlobalRotMem : public Benchmark {
method RotationLocalToGlobalRotMem (line 116) | RotationLocalToGlobalRotMem() : Benchmark("rotationL2GRotMem") {}
method init (line 118) | void init() override {
method run (line 128) | void run() override {
FILE: benchmarks/threadResponseTime.cpp
type P3D (line 13) | namespace P3D {
class ThreadCreateBenchmark (line 14) | class ThreadCreateBenchmark : public Benchmark {
method ThreadCreateBenchmark (line 16) | ThreadCreateBenchmark() : Benchmark("threadCreateResponseTime") {}
method init (line 18) | virtual void init() override {}
method run (line 20) | virtual void run() override {
method printResults (line 48) | virtual void printResults(double timeTaken) override {}
class ThreadPoolBenchmark (line 52) | class ThreadPoolBenchmark : public Benchmark {
method ThreadPoolBenchmark (line 54) | ThreadPoolBenchmark() : Benchmark("threadPoolResponseTime") {}
method init (line 56) | virtual void init() override {}
method run (line 58) | virtual void run() override {
method printResults (line 86) | virtual void printResults(double timeTaken) override {}
FILE: benchmarks/worldBenchmark.cpp
type P3D (line 21) | namespace P3D {
function printToLength (line 61) | void printToLength(std::string text, std::size_t length) {
function TerminalColor (line 86) | TerminalColor getColor(std::size_t i) {
function printBreakdown (line 96) | void printBreakdown(const T* values, const char** labels, std::size_t ...
FILE: benchmarks/worldBenchmark.h
function namespace (line 6) | namespace P3D {
FILE: engine/ecs/registry.h
function namespace (line 14) | namespace P3D::Engine {
function entity_set_iterator (line 311) | entity_set_iterator begin() noexcept {
function entity_set_iterator (line 315) | entity_set_iterator end() noexcept {
function entity_type (line 525) | entity_type destroy(const entity_type& entity) noexcept {
function Component (line 679) | [[nodiscard]] Component getOr(const entity_type& entity, Args&&... args) {
function contains (line 690) | [[nodiscard]] bool contains(const entity_type& entity) noexcept {
function has (line 698) | [[nodiscard]] bool has(const entity_type& entity) noexcept {
function has (line 705) | [[nodiscard]] bool has(const entity_type& entity, const component_type& ...
function entity_type (line 739) | [[nodiscard]] constexpr entity_type getParent(const representation_type&...
function entity_type (line 746) | [[nodiscard]] constexpr entity_type getParent(const entity_type& entity) {
function entity_type (line 757) | [[nodiscard]] constexpr entity_type getSelf(const representation_type& e...
function entity_type (line 764) | [[nodiscard]] constexpr entity_type getSelf(const entity_type& entity) {
function setParent (line 771) | bool setParent(const entity_type& entity, const entity_type& parent) noe...
function noexcept (line 794) | [[nodiscard]] auto getChildren(const entity_type& entity) noexcept {
function noexcept (line 815) | [[nodiscard]] auto getChildren(const representation_type& entity) noexce...
function noexcept (line 835) | [[nodiscard]] auto view(type<conj<Component, Components...>>) noexcept {
function noexcept (line 870) | [[nodiscard]] auto view(type<disj<Components...>>) noexcept {
function filter (line 890) | auto filter = [entity](const component_vector_iterator& iterator) {
function filter (line 933) | auto filter = [this](const entity_set_iterator& iterator) {
function noexcept (line 981) | [[nodiscard]] auto view() noexcept {
type Registry (line 993) | typedef Registry<std::uint16_t> Registry16;
type Registry (line 994) | typedef Registry<std::uint32_t> Registry32;
type Registry (line 995) | typedef Registry<std::uint64_t> Registry64;
FILE: engine/event/event.h
function namespace (line 5) | namespace P3D::Engine {
FILE: engine/event/keyEvent.h
function namespace (line 7) | namespace P3D::Engine {
FILE: engine/event/mouseEvent.h
function namespace (line 7) | namespace P3D::Engine {
function class (line 58) | class MouseScrollEvent : public MouseEvent {
function class (line 77) | class MouseEnterEvent : public MouseEvent {
function class (line 111) | class MousePressEvent : public MouseButtonEvent {
function class (line 118) | class MouseReleaseEvent : public MouseButtonEvent {
function class (line 125) | class MouseDragEvent : public MouseButtonEvent {
FILE: engine/event/windowEvent.h
function namespace (line 5) | namespace P3D::Engine {
FILE: engine/input/inputHandler.cpp
type P3D::Engine (line 13) | namespace P3D::Engine {
function Vec2 (line 134) | Vec2 InputHandler::getMousePosition() const {
FILE: engine/input/inputHandler.h
function namespace (line 6) | namespace P3D::Engine {
FILE: engine/input/keyboard.cpp
type P3D::Engine (line 9) | namespace P3D::Engine {
type Keyboard (line 78) | namespace Keyboard {
function Key (line 332) | Key getKey(const std::string& name) {
function Key (line 341) | Key getKey(int code) {
FILE: engine/input/keyboard.h
function namespace (line 3) | namespace P3D::Engine {
FILE: engine/input/modifiers.cpp
type P3D::Engine (line 7) | namespace P3D::Engine {
type Modifier (line 29) | namespace Modifier {
FILE: engine/input/modifiers.h
function namespace (line 3) | namespace P3D::Engine {
FILE: engine/input/mouse.cpp
type P3D::Engine (line 9) | namespace P3D::Engine {
type Mouse (line 46) | namespace Mouse {
function Button (line 77) | Button getButton(std::string name) {
function Button (line 86) | Button getButton(int code) {
FILE: engine/input/mouse.h
function namespace (line 3) | namespace P3D::Engine {
FILE: engine/io/export.cpp
type P3D (line 12) | namespace P3D {
function saveBinaryObj (line 83) | void saveBinaryObj(std::string filename, const Graphics::ExtendedTrian...
function saveNonBinaryObj (line 136) | void saveNonBinaryObj(const std::string& filename, const Graphics::Ext...
FILE: engine/io/export.h
function namespace (line 3) | namespace P3D::Graphics {
function namespace (line 7) | namespace P3D {
FILE: engine/io/import.cpp
type P3D (line 12) | namespace P3D {
function Vec3 (line 39) | Vec3 Import::parseVec3(const std::string& vec) {
function Position (line 48) | Position Import::parsePosition(const std::string& vec) {
function Vec4 (line 53) | Vec4 Import::parseVec4(const std::string& vec) {
function Vec4f (line 62) | Vec4f Import::parseVec4f(const std::string& vec) {
function Vec3f (line 71) | Vec3f Import::parseVec3f(const std::string& vec) {
function DiagonalMat3 (line 80) | DiagonalMat3 Import::parseDiagonalMat3(const std::string& mat) {
function Mat3 (line 89) | Mat3 Import::parseMat3(const std::string& mat) {
function T (line 100) | T Import::read(std::istream& input) {
type Vertex (line 116) | struct Vertex {
method Vertex (line 121) | Vertex() : position(0), normal(std::nullopt), uv(std::nullopt) {}
method Vertex (line 123) | Vertex(const std::string_view& line) {
type VertexHasher (line 144) | struct VertexHasher {
type Face (line 159) | struct Face {
method Face (line 162) | Face(const Vertex& v1, const Vertex& v2, const Vertex& v3) {
method Vertex (line 168) | Vertex& operator[](std::size_t index) {
method Vertex (line 174) | const Vertex& operator[](int index) const {
function reorderWithoutSharedVerticesSupport (line 181) | Graphics::ExtendedTriangleMesh reorderWithoutSharedVerticesSupport(con...
function reorderWithSharedVerticesSupport (line 257) | Graphics::ExtendedTriangleMesh reorderWithSharedVerticesSupport(const ...
function loadBinaryObj (line 327) | Graphics::ExtendedTriangleMesh loadBinaryObj(std::istream& input) {
function loadNonBinaryObj (line 409) | Graphics::ExtendedTriangleMesh loadNonBinaryObj(std::istream& input) {
FILE: engine/io/import.h
function namespace (line 5) | namespace P3D::Graphics {
function namespace (line 9) | namespace P3D {
FILE: engine/layer/layer.h
function namespace (line 8) | namespace P3D::Engine {
FILE: engine/layer/layerStack.cpp
type P3D::Engine (line 5) | namespace P3D::Engine {
FILE: engine/layer/layerStack.h
function namespace (line 6) | namespace P3D::Engine {
FILE: engine/options/keyboardOptions.cpp
type P3D::Engine (line 5) | namespace P3D::Engine {
type KeyboardOptions (line 7) | namespace KeyboardOptions {
type Move (line 9) | namespace Move {
type Rotate (line 20) | namespace Rotate {
type Tick (line 27) | namespace Tick {
type Speed (line 30) | namespace Speed {
type Debug (line 36) | namespace Debug {
type Edit (line 43) | namespace Edit {
type Part (line 51) | namespace Part {
type Application (line 58) | namespace Application {
type World (line 62) | namespace World {
function Key (line 66) | Key loadKey(const Util::Properties& properties, std::string key) {
function saveKey (line 70) | void saveKey(Util::Properties& properties, std::string property, con...
function load (line 74) | void load(const Util::Properties& properties) {
function save (line 123) | void save(Util::Properties& properties) {
FILE: engine/options/keyboardOptions.h
function namespace (line 6) | namespace P3D::Engine {
FILE: engine/resource/meshResource.cpp
type P3D::Engine (line 7) | namespace P3D::Engine {
function MeshResource (line 9) | MeshResource* MeshAllocator::load(const std::string& name, const std::...
FILE: engine/resource/meshResource.h
function namespace (line 8) | namespace P3D::Engine {
FILE: engine/tool/buttonTool.h
function namespace (line 5) | namespace P3D::Engine {
FILE: engine/tool/stateTool.h
function namespace (line 5) | namespace P3D::Engine {
FILE: engine/tool/tool.h
function namespace (line 5) | namespace P3D::Engine {
FILE: engine/tool/toolManager.cpp
type P3D::Engine (line 7) | namespace P3D::Engine {
function ToolManager (line 17) | ToolManager& ToolManager::operator=(ToolManager&& other) noexcept {
FILE: engine/tool/toolManager.h
function namespace (line 5) | namespace P3D::Engine {
FILE: examples/openglBasic.cpp
function GLFWwindow (line 26) | GLFWwindow* initWindow() {
type Color (line 60) | struct Color {
type Colors (line 71) | namespace Colors {
function GLuint (line 113) | GLuint loadShaders(const char* vertexShaderSourceCode, const char* fragm...
class RenderShader (line 174) | class RenderShader {
method RenderShader (line 183) | RenderShader() {
method setModelMatrix (line 192) | void setModelMatrix(Mat4f modelMatrix) {
method setPVMatrix (line 197) | void setPVMatrix(Mat4f pvMatrix) {
method setLightDirection (line 202) | void setLightDirection(Vec3f lightDirection) {
method setPartColor (line 205) | void setPartColor(Color color) {
class ArrayMesh (line 210) | class ArrayMesh {
method ArrayMesh (line 218) | ArrayMesh() : vertexArrayID(INVALID), vertexBuffer(INVALID), normalsBu...
method ArrayMesh (line 219) | ArrayMesh(const float* vertexData, const float* normalsData, size_t tr...
method ArrayMesh (line 243) | ArrayMesh(ArrayMesh&) = delete;
method ArrayMesh (line 244) | ArrayMesh& operator=(ArrayMesh&) = delete;
method ArrayMesh (line 245) | ArrayMesh(ArrayMesh&& other) noexcept :
method ArrayMesh (line 255) | ArrayMesh& operator=(ArrayMesh&& other) noexcept {
method bind (line 263) | void bind() const {
method unbind (line 288) | void unbind() const {
method render (line 292) | void render() const {
class MeshRegistry (line 302) | class MeshRegistry {
method findKnownShapeClassIndex (line 306) | int findKnownShapeClassIndex(const ShapeClass* shapeClass) {
method registerShapeClassMesh (line 315) | int registerShapeClassMesh(const ShapeClass* shapeClass, ArrayMesh&& m...
method getMeshIndexFor (line 320) | int getMeshIndexFor(const ShapeClass* shapeClass) {
method ArrayMesh (line 345) | const ArrayMesh& operator[](int meshIndex) const {
class CustomPart (line 352) | class CustomPart : public Part {
method CustomPart (line 359) | CustomPart(const Shape& shape, const GlobalCFrame& position, const Par...
method CustomPart (line 362) | CustomPart(const Shape& shape, const GlobalCFrame& position, const Par...
function render (line 366) | void render(World<CustomPart>& world, UpgradeableMutex& worldMutex, Rend...
function main (line 386) | int main(int argc, const char** argv) {
FILE: graphics/batch/batch.h
function namespace (line 11) | namespace P3D::Graphics {
FILE: graphics/batch/batchConfig.h
function namespace (line 5) | namespace P3D::Graphics {
FILE: graphics/batch/commandBatch.h
function namespace (line 7) | namespace P3D::Graphics {
FILE: graphics/batch/guiBatch.h
function namespace (line 9) | namespace P3D::Graphics {
FILE: graphics/batch/instanceBatch.h
function namespace (line 16) | namespace P3D::Graphics {
FILE: graphics/batch/instanceBatchManager.h
function namespace (line 10) | namespace P3D::Graphics {
FILE: graphics/bindable.cpp
type P3D::Graphics (line 5) | namespace P3D::Graphics {
function GLID (line 11) | GLID Bindable::getID() const {
FILE: graphics/bindable.h
type GLID (line 3) | typedef unsigned int GLID;
function namespace (line 5) | namespace P3D::Graphics {
FILE: graphics/buffers/bufferLayout.cpp
type P3D::Graphics (line 7) | namespace P3D::Graphics {
type BufferDataType (line 9) | namespace BufferDataType {
FILE: graphics/buffers/bufferLayout.h
function namespace (line 3) | namespace P3D::Graphics {
FILE: graphics/buffers/frameBuffer.cpp
type P3D::Graphics (line 12) | namespace P3D::Graphics {
FILE: graphics/buffers/frameBuffer.h
function bind (line 67) | void bind() override;
FILE: graphics/buffers/indexBuffer.cpp
type P3D::Graphics (line 7) | namespace P3D::Graphics {
function IndexBuffer (line 32) | IndexBuffer& IndexBuffer::operator=(IndexBuffer&& other) {
FILE: graphics/buffers/indexBuffer.h
function namespace (line 6) | namespace P3D::Graphics {
FILE: graphics/buffers/renderBuffer.cpp
type P3D::Graphics (line 10) | namespace P3D::Graphics {
function RenderBuffer (line 29) | RenderBuffer& RenderBuffer::operator=(RenderBuffer&& other) {
function MultisampleRenderBuffer (line 80) | MultisampleRenderBuffer& MultisampleRenderBuffer::operator=(Multisampl...
FILE: graphics/buffers/renderBuffer.h
function namespace (line 5) | namespace P3D::Graphics {
FILE: graphics/buffers/vertexArray.cpp
type P3D::Graphics (line 10) | namespace P3D::Graphics {
function VertexArray (line 30) | VertexArray& VertexArray::operator=(VertexArray&& other) {
FILE: graphics/buffers/vertexArray.h
function namespace (line 5) | namespace P3D::Graphics {
FILE: graphics/buffers/vertexBuffer.cpp
type P3D::Graphics (line 7) | namespace P3D::Graphics {
function VertexBuffer (line 39) | VertexBuffer& VertexBuffer::operator=(VertexBuffer&& other) {
FILE: graphics/buffers/vertexBuffer.h
function namespace (line 7) | namespace P3D::Graphics {
FILE: graphics/debug/guiDebug.cpp
type P3D::Graphics (line 14) | namespace P3D::Graphics {
function renderQuad (line 16) | void renderQuad() {
function clearError (line 41) | void clearError() {
function logCall (line 45) | bool logCall(const char* func, const char* file, int line) {
type AppDebug (line 56) | namespace AppDebug {
type Logging (line 61) | namespace Logging {
function logVector (line 64) | void logVector(Position origin, Vec3 vec, VectorType type) {
function logPoint (line 68) | void logPoint(Position point, PointType type) {
function logCFrame (line 72) | void logCFrame(CFrame frame, CFrameType type) {
function logShape (line 93) | void logShape(const Polyhedron& shape, const GlobalCFrame& locatio...
function logTickStart (line 103) | void logTickStart() {
function logTickEnd (line 107) | void logTickEnd(WorldPrototype* world) {
function logFrameStart (line 112) | void logFrameStart() {
function logFrameEnd (line 116) | void logFrameEnd() {
function setupDebugHooks (line 120) | void setupDebugHooks() {
FILE: graphics/debug/guiDebug.h
function namespace (line 10) | namespace P3D {
type ColoredPoint (line 30) | struct ColoredPoint {
FILE: graphics/debug/profilerUI.cpp
type P3D::Graphics (line 19) | namespace P3D::Graphics {
function recursiveRenderTree (line 175) | static void recursiveRenderTree(const P3D::TreeTrunk& curTrunk, int cu...
function renderTreeStructure (line 200) | void renderTreeStructure(const P3D::BoundsTree<Part>& tree, const Colo...
function SlidingChartDataSetInfo (line 268) | SlidingChartDataSetInfo SlidingChart::get(const std::string& title) {
function Vec2 (line 309) | Vec2 SlidingChart::resize() {
FILE: graphics/debug/profilerUI.h
function namespace (line 7) | namespace P3D {
type WeightValue (line 19) | struct WeightValue {
type PieChart (line 33) | struct PieChart {
type BarChartClassInfo (line 47) | struct BarChartClassInfo {
type BarChart (line 52) | struct BarChart {
type SlidingChart (line 84) | struct SlidingChart {
FILE: graphics/debug/threePhaseBuffer.h
function namespace (line 7) | namespace P3D {
FILE: graphics/debug/visualDebug.cpp
type P3D::Graphics (line 19) | namespace P3D::Graphics {
type VisualDebug (line 37) | namespace VisualDebug {
type PointColorPair (line 57) | struct PointColorPair {
function toggleVectorType (line 90) | void toggleVectorType(P3D::Debug::VectorType type) {
function togglePointType (line 94) | void togglePointType(P3D::Debug::PointType type) {
function toString (line 98) | std::string toString(std::chrono::nanoseconds time) {
function getTheoreticalNumberOfIntersections (line 106) | size_t getTheoreticalNumberOfIntersections(size_t objectCount) {
function updateVectorMesh (line 110) | void updateVectorMesh(Graphics::VectorMesh* vectorMesh, AppDebug::Co...
function updatePointMesh (line 131) | void updatePointMesh(Graphics::PointMesh* pointMesh, AppDebug::Color...
function addDebugField (line 156) | void addDebugField(Vec2 dimension, Graphics::Font* font, const char*...
FILE: graphics/debug/visualDebug.h
function namespace (line 7) | namespace P3D::Graphics {
FILE: graphics/ecs/components.h
function namespace (line 10) | namespace P3D::Graphics::Comp {
FILE: graphics/ecs/materials.h
function namespace (line 5) | namespace P3D::Graphics {
FILE: graphics/extendedTriangleMesh.cpp
type P3D::Graphics (line 6) | namespace P3D::Graphics {
function ExtendedTriangleMesh (line 9) | ExtendedTriangleMesh ExtendedTriangleMesh::generateSmoothNormalsShape(...
function ExtendedTriangleMesh (line 20) | ExtendedTriangleMesh ExtendedTriangleMesh::generateSplitNormalsShape(c...
FILE: graphics/extendedTriangleMesh.h
function namespace (line 11) | namespace P3D::Graphics {
FILE: graphics/font.cpp
type P3D::Graphics (line 15) | namespace P3D::Graphics {
function Vec2f (line 126) | Vec2f Font::size(const std::string& text, double fontSize) {
function Character (line 147) | Character& Font::getCharacter(unsigned int id) {
FILE: graphics/font.h
function namespace (line 10) | namespace P3D::Graphics {
FILE: graphics/glfwUtils.cpp
type P3D::Graphics (line 12) | namespace P3D::Graphics {
type GLFW (line 14) | namespace GLFW {
type Cursor (line 16) | namespace Cursor {
function init (line 33) | bool init() {
function terminate (line 37) | void terminate() {
function setCurrentContext (line 41) | void setCurrentContext(GLFWwindow* context) {
function GLFWwindow (line 50) | GLFWwindow* createContext(int width, int height, const char* title) {
function validContext (line 56) | bool validContext(GLFWwindow* context) {
function GLFWwindow (line 60) | GLFWwindow* getCurrentContext() {
function isFullScreen (line 64) | bool isFullScreen() {
function setFullScreen (line 68) | void setFullScreen(bool fullscreen) {
function swapFullScreen (line 83) | void swapFullScreen() {
function swapInterval (line 87) | void swapInterval(int interval) {
function swapBuffers (line 91) | void swapBuffers() {
function pollEvents (line 95) | void pollEvents() {
function closeWindow (line 99) | void closeWindow() {
function isWindowClosed (line 103) | bool isWindowClosed() {
function setMultisampleSamples (line 107) | void setMultisampleSamples(int samples) {
function Vec2i (line 111) | Vec2i getWindowSize() {
function Vec4i (line 118) | Vec4i getFrameSize() {
function enableCursor (line 127) | void enableCursor() {
function disableCursor (line 131) | void disableCursor() {
function setCursor (line 135) | void setCursor(int type) {
function setWindowIcon (line 149) | void setWindowIcon(const GLFWimage* image) {
function setWindowIconFromPath (line 153) | void setWindowIconFromPath(const char* path) {
FILE: graphics/glfwUtils.h
type GLFWwindow (line 3) | struct GLFWwindow
type GLFWimage (line 4) | struct GLFWimage
function namespace (line 6) | namespace P3D::Graphics {
FILE: graphics/gui/color.h
function namespace (line 5) | namespace P3D::Graphics {
function T (line 38) | constexpr T& operator[](size_t index) noexcept {
function ColorTemplate (line 64) | constexpr static ColorTemplate<T> hsvaToRgba(const ColorTemplate<T>& hsv...
function ColorTemplate (line 97) | constexpr static ColorTemplate<T> rgbaToHsva(const ColorTemplate<T>& rgb...
function ColorTemplate (line 131) | constexpr static ColorTemplate<T> blend(const ColorTemplate<T>& color1, ...
type ColorTemplate (line 176) | typedef ColorTemplate<float> Color;
function namespace (line 178) | namespace Colors {
FILE: graphics/gui/gui.cpp
type P3D::Graphics (line 6) | namespace P3D::Graphics {
type GUI (line 8) | namespace GUI {
function onInit (line 17) | void onInit(const WindowInfo& info) {
function onWindowResize (line 29) | bool onWindowResize(const WindowInfo& info) {
function onUpdate (line 35) | void onUpdate(const Mat4f& orthoMatrix) {
function onClose (line 39) | void onClose() {
FILE: graphics/gui/gui.h
function namespace (line 6) | namespace P3D::Graphics {
FILE: graphics/gui/guiUtils.cpp
type P3D::Graphics (line 7) | namespace P3D::Graphics {
type GUI (line 9) | namespace GUI {
function clamp (line 11) | double clamp(double value, double min, double max) {
function clamp (line 18) | float clamp(float value, float min, float max) {
function smoothstep (line 26) | double smoothstep(double start, double end, double x) {
function smoothstep (line 31) | float smoothstep(float start, float end, float x) {
function map (line 36) | double map(double x, double minIn, double maxIn, double minOut, doub...
function Vec2 (line 40) | Vec2 map(const Vec2& point) {
function Vec4 (line 46) | Vec4 mapRegion(const Vec4& region, const Vec2& inXDimension, const V...
function Vec2 (line 55) | Vec2 mapDimension(const Vec2& point, const Vec2& inXDimension, const...
function Vec2 (line 59) | Vec2 unmap(const Vec2& point) {
function Vec2 (line 63) | Vec2 mapDimension(const Vec2& dimension) {
function Vec2 (line 67) | Vec2 unmapDimension(const Vec2& dimension) {
function between (line 71) | bool between(double value, double min, double max) {
function minmax (line 75) | std::pair<double, double> minmax(double value1, double value2) {
FILE: graphics/gui/guiUtils.h
function namespace (line 3) | namespace P3D::Graphics {
FILE: graphics/gui/imgui/imguiExtension.h
function namespace (line 9) | namespace ImGui {
function DrawLine (line 24) | inline void DrawLine(const ImVec2& pos1, const ImVec2& pos2) {
function DrawIcon (line 40) | inline void DrawIcon(GLID icon, const ImVec2& min, const ImVec2& max) {
function ImU32 (line 47) | inline ImU32 HexToImU32(const char* hex) {
function InputDouble3 (line 61) | inline bool InputDouble3(const char* label, double v[3], ImGuiInputTextF...
function InputFloat9 (line 66) | inline bool InputFloat9(const char* label, float v[9], ImGuiInputTextFla...
function HelpMarker (line 174) | inline void HelpMarker(const char* description) {
function BeginToolbar (line 185) | inline void BeginToolbar(const char* name) {
function ToolBarSpacing (line 219) | inline void ToolBarSpacing() {
function EndToolBar (line 224) | inline void EndToolBar() {
FILE: graphics/gui/imgui/imguiStyle.cpp
type P3D::Graphics (line 4) | namespace P3D::Graphics {
function renderImGuiStyleEditor (line 13) | void renderImGuiStyleEditor() {
function setupImGuiLayoutStyle (line 53) | void setupImGuiLayoutStyle(ImGuiStyle* style) {
function setupImGuiAccent (line 83) | void setupImGuiAccent(ImGuiStyle* style) {
function setupImGuiColors (line 109) | void setupImGuiColors(ImGuiStyle* style, ImGuiColors colors) {
function setupImGuiStyle (line 177) | void setupImGuiStyle() {
FILE: graphics/gui/imgui/imguiStyle.h
function namespace (line 4) | namespace P3D::Graphics {
FILE: graphics/gui/imgui/legacy_imgui_impl_glfw.cpp
type GlfwClientApi (line 18) | enum GlfwClientApi {
function ImGuiSetClipboardText (line 38) | static void ImGuiSetClipboardText(void* user_data, const char* text) {
function ImGuiMouseButtonCallback (line 42) | void ImGuiMouseButtonCallback(GLFWwindow* window, int button, int action...
function ImGuiScrollCallback (line 50) | void ImGuiScrollCallback(GLFWwindow* window, double xoffset, double yoff...
function ImGuiKeyCallback (line 59) | void ImGuiKeyCallback(GLFWwindow* window, int key, int scancode, int act...
function ImGuiCharCallback (line 76) | void ImGuiCharCallback(GLFWwindow* window, unsigned int c) {
function ImGuiInitGLFW (line 84) | bool ImGuiInitGLFW(GLFWwindow* window, bool install_callbacks) {
function ImGuiShutdownGLFW (line 152) | void ImGuiShutdownGLFW() {
function ImGuiUpdateMousePosAndButtons (line 169) | static void ImGuiUpdateMousePosAndButtons() {
function ImGuiUpdateMouseCursor (line 195) | static void ImGuiUpdateMouseCursor() {
function ImGuiNewFrameGLFW (line 212) | void ImGuiNewFrameGLFW() {
FILE: graphics/gui/imgui/legacy_imgui_impl_glfw.h
type GLFWwindow (line 3) | struct GLFWwindow
FILE: graphics/gui/imgui/legacy_imgui_impl_opengl3.cpp
function ImGuiInitOpenGl (line 140) | bool ImGuiInitOpenGl(const char* glsl_version)
function ImGuiShutdownOpenGL (line 202) | void ImGuiShutdownOpenGL()
function ImGuiNewFrameOpenGL (line 207) | void ImGuiNewFrameOpenGL()
function ImGui_ImplOpenGL3_SetupRenderState (line 213) | static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, in...
function ImGuiRenderDrawData (line 266) | void ImGuiRenderDrawData(ImDrawData* draw_data)
function ImGui_ImplOpenGL3_CreateFontsTexture (line 401) | bool ImGui_ImplOpenGL3_CreateFontsTexture()
function ImGui_ImplOpenGL3_DestroyFontsTexture (line 430) | void ImGui_ImplOpenGL3_DestroyFontsTexture()
function CheckShader (line 442) | static bool CheckShader(GLuint handle, const char* desc)
function CheckProgram (line 460) | static bool CheckProgram(GLuint handle, const char* desc)
function ImGui_ImplOpenGL3_CreateDeviceObjects (line 477) | bool ImGui_ImplOpenGL3_CreateDeviceObjects()
function ImGui_ImplOpenGL3_DestroyDeviceObjects (line 657) | void ImGui_ImplOpenGL3_DestroyDeviceObjects()
FILE: graphics/gui/orderedVector.h
function insert (line 26) | inline void insert(const T& element) {
function add (line 30) | inline void add(const T& element) {
function remove (line 34) | inline void remove(typename std::vector<T>::const_iterator iterator) {
function remove (line 38) | inline void remove(const T& element) {
function select (line 45) | inline void select(const T& element) {
function T (line 60) | T operator[](size_t index) const {
FILE: graphics/legacy/button.cpp
function Vec2 (line 72) | Vec2 Button::resize() {
FILE: graphics/legacy/button.h
function class (line 10) | class Button : public Component {
FILE: graphics/legacy/checkBox.cpp
function Vec2 (line 123) | Vec2 CheckBox::resize() {
FILE: graphics/legacy/checkBox.h
function class (line 11) | class CheckBox : public Component {
FILE: graphics/legacy/colorPicker.cpp
function Vec2 (line 105) | Vec2 ColorPicker::resize() {
function Color (line 118) | Color ColorPicker::getRgba() {
FILE: graphics/legacy/colorPicker.h
function class (line 10) | class ColorPicker : public Component {
FILE: graphics/legacy/component.h
function namespace (line 8) | namespace P3D::Graphics {
FILE: graphics/legacy/container.cpp
type P3D::Graphics (line 9) | namespace P3D::Graphics {
function Component (line 52) | Component* Container::intersect(Vec2 point) {
FILE: graphics/legacy/container.h
function namespace (line 6) | namespace P3D::Graphics {
FILE: graphics/legacy/cshader.cpp
type P3D::Graphics (line 16) | namespace P3D::Graphics {
function GLID (line 20) | GLID CShader::createShader(const ShaderSource& shaderSource) {
function CShader (line 62) | CShader& CShader::operator=(CShader&& other) {
FILE: graphics/legacy/cshader.h
function namespace (line 5) | namespace P3D::Graphics {
FILE: graphics/legacy/directionEditor.cpp
function Vec2 (line 54) | Vec2 DirectionEditor::resize() {
FILE: graphics/legacy/directionEditor.h
function class (line 9) | class DirectionEditor : public Component {
FILE: graphics/legacy/frame.cpp
function Vec2 (line 84) | Vec2 Frame::resize() {
function Component (line 122) | Component* Frame::intersect(Vec2 point) {
FILE: graphics/legacy/frame.h
function class (line 9) | class Frame : public Container {
FILE: graphics/legacy/gshader.cpp
type P3D::Graphics (line 16) | namespace P3D::Graphics {
function GLID (line 20) | GLID GShader::createShader(const ShaderSource& shaderSource) {
function ShaderSource (line 107) | ShaderSource parseShader(const std::string& name, const std::string& p...
function GShader (line 200) | GShader& GShader::operator=(GShader&& other) {
FILE: graphics/legacy/gshader.h
function namespace (line 5) | namespace P3D::Graphics {
FILE: graphics/legacy/image.cpp
function Vec2 (line 52) | Vec2 Image::resize() {
function Image (line 75) | Image* Image::fixHeight(float height) {
function Image (line 82) | Image* Image::fixWidth(float width) {
FILE: graphics/legacy/image.h
function class (line 7) | class Image : public Component {
FILE: graphics/legacy/label.cpp
function Vec2 (line 44) | Vec2 Label::resize() {
FILE: graphics/legacy/label.h
function class (line 7) | class Label : public Component {
FILE: graphics/legacy/layout.cpp
type P3D::Graphics (line 7) | namespace P3D::Graphics {
function Vec2 (line 9) | Vec2 FlowLayout::resize(Container* container, Vec2 minDimension) {
FILE: graphics/legacy/layout.h
function namespace (line 3) | namespace P3D::Graphics {
FILE: graphics/legacy/panel.cpp
function Vec2 (line 23) | Vec2 Panel::resize() {
FILE: graphics/legacy/panel.h
function class (line 6) | class Panel : public Container {
FILE: graphics/legacy/shader.cpp
type P3D::Graphics (line 13) | namespace P3D::Graphics {
function GLID (line 123) | GLID Shader::compile(const std::string& name, const std::string& sourc...
function ShaderSource (line 160) | ShaderSource parseShader(const std::string& name, const std::string& p...
function ShaderSource (line 165) | ShaderSource parseShader(const std::string& name, const std::string& p...
function ShaderSource (line 179) | ShaderSource parseShader(const std::string& name, const std::string& p...
function Shader (line 311) | Shader& Shader::operator=(Shader&& other) noexcept {
function getSuffixes (line 356) | std::vector<std::string> getSuffixes(const ShaderStage& stage, const P...
FILE: graphics/legacy/shader.h
function namespace (line 6) | namespace P3D::Graphics {
FILE: graphics/legacy/shaderLexer.cpp
type P3D::Graphics (line 6) | namespace P3D::Graphics {
function lexSingleComment (line 36) | std::string lexSingleComment(const std::string& input) {
function TokenType (line 44) | TokenType ShaderLexer::getMatch(const std::string& input) {
function Token (line 62) | Token ShaderLexer::popToken(std::string& input, const TokenType& type,...
function Token (line 88) | Token ShaderLexer::nextToken(std::string& input) {
function TokenStack (line 119) | TokenStack ShaderLexer::lexDebug(const std::string& input) {
function TokenStack (line 235) | TokenStack ShaderLexer::lex(const std::string& input) {
function Token (line 254) | Token TokenStack::peek(size_t offset) const {
function Token (line 262) | Token TokenStack::pop() {
function TokenStack (line 294) | TokenStack TokenStack::until(const TokenType::Type& type, bool popType) {
FILE: graphics/legacy/shaderLexer.h
function namespace (line 6) | namespace P3D::Graphics {
type Token (line 55) | struct Token {
FILE: graphics/legacy/shaderParser.cpp
type P3D::Graphics (line 5) | namespace P3D::Graphics {
function ShaderVariableType (line 25) | ShaderVariableType ShaderParser::parseVariableType(const std::string& ...
function ShaderIOType (line 33) | ShaderIOType parseIOType(const Token& token) {
function TokenStack (line 44) | TokenStack nextScope(TokenStack& tokens, const TokenType::Type& ltype,...
function testFunction (line 67) | bool testFunction(TokenStack& tokens) {
function parseArray (line 78) | int parseArray(TokenStack& tokens, const ShaderDefines& defines) {
function ShaderLocals (line 98) | ShaderLocals parseStructContent(TokenStack& scope, const ShaderStructs...
function ShaderStruct (line 123) | ShaderStruct parseStruct(TokenStack& tokens, const ShaderStructs& stru...
function ShaderUniform (line 133) | ShaderUniform parseUniform(TokenStack& tokens, const ShaderDefines& de...
function ShaderVSOUT (line 144) | ShaderVSOUT parseVSOUT(TokenStack& tokens, const std::string& ioType, ...
function ShaderLocal (line 153) | ShaderLocal parseLocal(TokenStack& tokens, const ShaderDefines& define...
function ShaderGlobal (line 161) | ShaderGlobal parseGlobal(TokenStack& tokens, const ShaderDefines& defi...
function ShaderLayoutItem (line 180) | ShaderLayoutItem parseLayoutItem(TokenStack& tokens) {
function parseDefine (line 205) | void parseDefine(TokenStack& tokens, ShaderDefines& defines) {
function parseUnDef (line 220) | void parseUnDef(TokenStack& tokens, ShaderDefines& defines) {
function parseIf (line 227) | bool parseIf(TokenStack& tokens, ShaderDefines& defines) {
function parseIfDef (line 244) | bool parseIfDef(TokenStack& tokens, ShaderDefines& defines) {
function parseIfNDef (line 253) | bool parseIfNDef(TokenStack& tokens, ShaderDefines& defines) {
function parseIfBody (line 257) | void parseIfBody() {
function ShaderVersion (line 261) | ShaderVersion parseVersion(TokenStack& tokens) {
function parsePreprocessor (line 279) | void parsePreprocessor(TokenStack& tokens, ShaderDefines& defines) {
function ShaderInfo (line 295) | ShaderInfo ShaderParser::parse(const std::string& code) {
function ShaderInfo (line 304) | ShaderInfo ShaderParser::parseTokens(TokenStack& tokens) {
FILE: graphics/legacy/shaderParser.h
type class (line 8) | enum class
type class (line 25) | enum class
type ShaderGlobal (line 41) | struct ShaderGlobal {
type ShaderVSOUT (line 70) | struct ShaderVSOUT
type ShaderVersion (line 76) | struct ShaderVersion {
type ShaderStruct (line 81) | struct ShaderStruct {
FILE: graphics/legacy/slider.cpp
function Vec2 (line 78) | Vec2 Slider::resize() {
FILE: graphics/legacy/slider.h
function class (line 9) | class Slider : public Component {
FILE: graphics/legacy/text.h
type Word (line 7) | struct Word {
type Line (line 20) | struct Line {
type TextFlags (line 35) | enum TextFlags : char {
type Text (line 57) | struct Text {
function class (line 74) | class TextLoader {
FILE: graphics/mesh/abstractMesh.cpp
type P3D::Graphics (line 8) | namespace P3D::Graphics {
FILE: graphics/mesh/abstractMesh.h
function namespace (line 6) | namespace P3D::Graphics {
FILE: graphics/mesh/arrayMesh.cpp
type P3D::Graphics (line 10) | namespace P3D::Graphics {
FILE: graphics/mesh/arrayMesh.h
function namespace (line 7) | namespace P3D::Graphics {
FILE: graphics/mesh/indexedMesh.cpp
type P3D::Graphics (line 11) | namespace P3D::Graphics {
function IndexedMesh (line 133) | IndexedMesh& IndexedMesh::operator=(IndexedMesh&& other) {
FILE: graphics/mesh/indexedMesh.h
function namespace (line 11) | namespace P3D::Graphics {
FILE: graphics/mesh/pointMesh.cpp
type P3D::Graphics (line 9) | namespace P3D::Graphics {
FILE: graphics/mesh/pointMesh.h
function namespace (line 5) | namespace P3D::Graphics {
FILE: graphics/mesh/primitive.h
function namespace (line 6) | namespace P3D::Graphics {
function Primitive (line 61) | struct Quad : public Primitive {
function resize (line 71) | void resize(Vec2f position, Vec2f dimension, Vec2f xRange, Vec2f yRange) {
function resize (line 90) | void resize(Vec2f position, Vec2f dimension) {
function render (line 102) | void render(int mode) {
function render (line 114) | void render() override {
function Primitive (line 122) | struct LinePrimitive : public Primitive {
function render (line 146) | void render(int mode) {
function render (line 158) | void render() override {
function Primitive (line 166) | struct TrianglePrimitive : public Primitive {
function resize (line 175) | void resize(Vec3f p1, Vec3f p2, Vec3f p3) {
function resize (line 185) | void resize(Vec2f p1, Vec2f p2, Vec2f p3) {
function render (line 196) | void render(int mode) {
function render (line 208) | void render() override {
FILE: graphics/mesh/vectorMesh.cpp
type P3D::Graphics (line 10) | namespace P3D::Graphics {
FILE: graphics/mesh/vectorMesh.h
function namespace (line 5) | namespace P3D::Graphics {
FILE: graphics/meshRegistry.cpp
type P3D::Graphics::MeshRegistry (line 14) | namespace P3D::Graphics::MeshRegistry {
function ExtendedTriangleMesh (line 27) | ExtendedTriangleMesh createQuad(const Vec3f& center, const Vec3f& norm...
function ExtendedTriangleMesh (line 72) | ExtendedTriangleMesh createCylinder(int sides, double radius, double h...
function ExtendedTriangleMesh (line 149) | ExtendedTriangleMesh createSphere(double radius, int steps) {
function ExtendedTriangleMesh (line 172) | ExtendedTriangleMesh createBox(float width, float height, float depth) {
function ExtendedTriangleMesh (line 203) | ExtendedTriangleMesh createCube(float size) {
function ExtendedTriangleMesh (line 207) | ExtendedTriangleMesh createHexagon(float radius, float height) {
function generateCylindricalUVs (line 213) | void generateCylindricalUVs(ExtendedTriangleMesh& mesh) {
function generateSphericalUVs (line 233) | void generateSphericalUVs(ExtendedTriangleMesh& mesh) {
function generateLightProbeUVs (line 254) | void generateLightProbeUVs(ExtendedTriangleMesh& mesh) {
function init (line 277) | void init() {
function registerShape (line 287) | Comp::Mesh registerShape(IndexedMesh* mesh, Comp::Mesh::Flags flags) {
function registerShape (line 295) | Comp::Mesh registerShape(const ExtendedTriangleMesh& mesh) {
function registerShapeClass (line 303) | Comp::Mesh registerShapeClass(const ShapeClass* shapeClass, const Exte...
function registerShapeClass (line 315) | Comp::Mesh registerShapeClass(const ShapeClass* shapeClass) {
function getMesh (line 325) | Comp::Mesh getMesh(const ShapeClass* shapeClass) {
function getID (line 334) | std::size_t getID(const ShapeClass* shapeClass) {
function IndexedMesh (line 343) | IndexedMesh* get(std::size_t id) {
function IndexedMesh (line 347) | IndexedMesh* get(const Comp::Mesh& mesh) {
function IndexedMesh (line 354) | IndexedMesh* get(const ShapeClass* shapeClass) {
FILE: graphics/meshRegistry.h
function namespace (line 7) | namespace P3D::Graphics::MeshRegistry {
FILE: graphics/path/path.cpp
type P3D::Graphics (line 11) | namespace P3D::Graphics {
type Path (line 13) | namespace Path {
function bind (line 21) | void bind(GuiBatch* batch) {
function submit (line 25) | void submit() {
function pushQuad (line 32) | void pushQuad(const Vec2f& a, const Vec2f& b, const Vec2f& c, const ...
function pushTriangle (line 40) | void pushTriangle(const Vec2f& a, const Vec2f& b, const Vec2f& c, co...
function pushLine (line 47) | void pushLine(const Vec2f& a, const Vec2f& b, const Color& colorA, c...
function line (line 59) | void line(const Vec2f& a, const Vec2f& b, const Color& color, float ...
function line (line 63) | void line(const Vec2f& a, const Vec2f& b, const Color& colorA, const...
function circle (line 71) | void circle(const Vec2f& center, float radius, const Color& color, f...
function circleFilled (line 89) | void circleFilled(const Vec2f& center, float radius, const Color& co...
function circleSegment (line 108) | void circleSegment(const Vec2f& center, float radius, float minAngle...
function circleSegmentFilled (line 133) | void circleSegmentFilled(const Vec2f& center, float radius, float mi...
function triangle (line 158) | void triangle(const Vec2f& a, const Vec2f& b, const Vec2f& c, const ...
function triangleFilled (line 168) | void triangleFilled(const Vec2f& a, const Vec2f& b, const Vec2f& c, ...
function rect (line 176) | void rect(const Vec2f& pos, const Vec2f& dim, float rounding, const ...
function rectFilled (line 183) | void rectFilled(const Vec2f& pos, const Vec2f& dim, float rounding, ...
function rectUV (line 194) | void rectUV(GLID id, const Vec2f& pos, const Vec2f& dim, const Vec2f...
function rectUVRange (line 213) | void rectUVRange(GLID id, const Vec2f& pos, const Vec2f& dim, const ...
function quad (line 240) | void quad(const Vec2f& a, const Vec2f& b, const Vec2f& c, const Vec2...
function quadFilled (line 251) | void quadFilled(const Vec2f& a, const Vec2f& b, const Vec2f& c, cons...
function quadUV (line 259) | void quadUV(GLID id, const Vec2f& a, const Vec2f& b, const Vec2f& c,...
function text (line 268) | void text(Font* font, const std::string& text, double size, const Ve...
function bezier (line 328) | void bezier(const Vec2f& a, const Vec2f& b, const Vec2f& c, const Ve...
function bezier (line 332) | void bezier(const Vec2f& a, const Vec2f& b, const Vec2f& c, const Ve...
function bezierHorizontal (line 358) | void bezierHorizontal(const Vec2f& start, const Vec2f& end, const Co...
function bezierHorizontal (line 362) | void bezierHorizontal(const Vec2f& start, const Vec2f& end, Pattern2...
function bezierVertical (line 369) | void bezierVertical(const Vec2f& start, const Vec2f& end, const Colo...
function bezierVertical (line 373) | void bezierVertical(const Vec2f& start, const Vec2f& end, Pattern2D ...
function polyLine (line 380) | void polyLine(Vec2f* points, size_t size, const Color& color, float ...
function polyLine (line 384) | void polyLine(Vec2f* points, size_t size, Pattern2D pattern, float t...
function polygonFilled (line 407) | void polygonFilled(Vec2f* points, size_t size, const Color& color) {
function polygonFilled (line 411) | void polygonFilled(Vec2f* points, size_t size, Pattern2D pattern) {
function catmullRom (line 440) | void catmullRom(Vec2f* points, size_t size, const Color& color, int ...
function catmullRom (line 444) | void catmullRom(Vec2f* points, size_t size, Pattern2D pattern, int p...
function lineTo (line 533) | void lineTo(const Vec2f& vertex) {
function arcTo (line 537) | void arcTo(const Vec2f& center, float radius, float minAngle, float ...
function bezierTo (line 551) | void bezierTo(const Vec2f& end, const Vec2f& tc1, const Vec2f& tc2, ...
function bezierTo (line 568) | void bezierTo(const Vec2f& end, size_t precision) {
function stroke (line 578) | void stroke(const Color& color, float thickness, bool closed) {
function stroke (line 582) | void stroke(Pattern2D pattern, float thickness, bool closed) {
function fill (line 588) | void fill(const Color& color) {
function fill (line 592) | void fill(Pattern2D pattern) {
function size (line 598) | int size() {
function clear (line 602) | void clear() {
FILE: graphics/path/path.h
function namespace (line 7) | namespace P3D::Graphics {
FILE: graphics/path/path3D.cpp
type P3D::Graphics (line 8) | namespace P3D::Graphics {
type Path3D (line 10) | namespace Path3D {
function bind (line 16) | void bind(Graphics::Batch<Vertex>* batch) {
function line (line 23) | void line(const Vec3f& a, const Vec3f& b, const Color& colorA, const...
function circle (line 34) | void circle(const Vec3f& center, float radius, const Vec3f& normal, ...
function triangle (line 64) | void triangle(const Vec3f& a, const Vec3f& b, const Vec3f& c, const ...
function quad (line 75) | void quad(const Vec3f& a, const Vec3f& b, const Vec3f& c, const Vec3...
function polyLine (line 86) | void polyLine(Vec3f* points, size_t size, Pattern3D pattern, float t...
function polyLine (line 112) | void polyLine(Vec3f* points, size_t size, const Color& color, float ...
function lineTo (line 120) | void lineTo(const Vec3f& vertex) {
function bezierTo (line 124) | void bezierTo(const Vec3f& end, const Vec3f& tc1, const Vec3f& tc2, ...
function bezierTo (line 141) | void bezierTo(const Vec3f& end, size_t precision) {
function stroke (line 152) | void stroke(const Color& color, float thickness, bool closed) {
function stroke (line 156) | void stroke(Pattern3D pattern, float thickness, bool closed) {
function size (line 161) | int size() {
function clear (line 165) | void clear() {
FILE: graphics/path/path3D.h
function namespace (line 6) | namespace P3D::Graphics {
FILE: graphics/renderer.cpp
type P3D::Graphics (line 8) | namespace P3D::Graphics {
type Renderer (line 10) | namespace Renderer {
function RenderState (line 36) | RenderState saveState() {
function loadState (line 70) | void loadState(const RenderState& state) {
function RenderState (line 91) | RenderState getState() {
function beginScene (line 125) | void beginScene() {
function endScene (line 130) | void endScene() {
function initGLEW (line 136) | bool initGLEW() {
function clearDepth (line 140) | void clearDepth() {
function clearColor (line 144) | void clearColor() {
function clearStencil (line 148) | void clearStencil() {
function lineStipple (line 152) | void lineStipple(int factor, short pattern) {
function lineWidth (line 156) | void lineWidth(float size) {
function viewport (line 160) | void viewport(const Vec2i& origin, const Vec2i& dimension) {
function enableDepthTest (line 168) | void enableDepthTest() {
function disableDepthTest (line 172) | void disableDepthTest() {
function enableDepthMask (line 176) | void enableDepthMask() {
function disableDepthMask (line 180) | void disableDepthMask() {
function enableCulling (line 184) | void enableCulling() {
function disableCulling (line 188) | void disableCulling() {
function enableBlending (line 192) | void enableBlending() {
function disableBlending (line 196) | void disableBlending() {
function standardBlendFunction (line 200) | void standardBlendFunction() {
function enableMultisampling (line 204) | void enableMultisampling() {
function polygonMode (line 208) | void polygonMode(int face, int mode) {
function parseShaderVersion (line 228) | int parseShaderVersion(const char* version) {
function getMaxTextureUnits (line 232) | int getMaxTextureUnits() {
function genBuffers (line 238) | void genBuffers(int count, GLID* id) {
function delBuffers (line 242) | void delBuffers(int count, GLID* id) {
function genVertexArrays (line 246) | void genVertexArrays(int count, GLID* id) {
function delVertexArrays (line 250) | void delVertexArrays(int count, GLID* id) {
function bindBuffer (line 254) | void bindBuffer(GLFLAG target, GLID id) {
function bufferData (line 258) | void bufferData(GLFLAG target, int size, int offset, GLFLAG type) {
function bufferSubData (line 262) | void bufferSubData(GLFLAG target, int offset, int size, const void* ...
function enableVertexAttribArray (line 266) | void enableVertexAttribArray(GLID id) {
function bindTexture2D (line 270) | void bindTexture2D(GLID id) {
function activeTexture (line 274) | void activeTexture(GLID unit) {
function vertexAttribPointer (line 278) | void vertexAttribPointer(GLID id, int size, GLFLAG type, bool normal...
function bindShader (line 282) | void bindShader(GLID id) {
function bindFramebuffer (line 289) | void bindFramebuffer(GLID id) {
function bindDrawbuffer (line 293) | void bindDrawbuffer(GLID id) {
function bindReadbuffer (line 300) | void bindReadbuffer(GLID id) {
function bindRenderbuffer (line 307) | void bindRenderbuffer(GLID id) {
function bindVertexArray (line 314) | void bindVertexArray(GLID id) {
function scissor (line 318) | void scissor(int x, int y, int width, int height) {
function drawElements (line 322) | void drawElements(GLFLAG mode, std::size_t count, GLFLAG type, const...
function drawElementsInstanced (line 326) | void drawElementsInstanced(GLFLAG mode, std::size_t count, GLFLAG ty...
function drawArrays (line 330) | void drawArrays(GLFLAG mode, int first, std::size_t count) {
function defaultSettings (line 334) | void defaultSettings(GLID defaultFrameBuffer) {
FILE: graphics/renderer.h
type GLFLAG (line 7) | typedef unsigned int GLFLAG;
function namespace (line 9) | namespace P3D::Graphics {
FILE: graphics/resource/fontResource.cpp
type P3D::Graphics (line 5) | namespace P3D::Graphics {
function FontResource (line 7) | FontResource* FontAllocator::load(const std::string& name, const std::...
FILE: graphics/resource/fontResource.h
function namespace (line 7) | namespace P3D::Graphics {
FILE: graphics/resource/shaderResource.cpp
type P3D::Graphics (line 8) | namespace P3D::Graphics {
function ShaderResource (line 10) | ShaderResource* ShaderAllocator::load(const std::string& name, const s...
FILE: graphics/resource/shaderResource.h
function namespace (line 6) | namespace P3D::Graphics {
FILE: graphics/resource/textureResource.cpp
type P3D::Graphics (line 5) | namespace P3D::Graphics {
function TextureResource (line 7) | TextureResource* TextureAllocator::load(const std::string& name, const...
FILE: graphics/resource/textureResource.h
function namespace (line 7) | namespace P3D::Graphics {
FILE: graphics/shader/lexer.cpp
type P3D::Graphics (line 3) | namespace P3D::Graphics {
FILE: graphics/shader/lexer.h
function namespace (line 6) | namespace P3D::Graphics {
function view (line 34) | struct Token {
FILE: graphics/shader/parser.cpp
type P3D::Graphics (line 8) | namespace P3D::Graphics {
function parseUntil (line 54) | void parseUntil(Lexer& lexer, Lexer::Token::Type ltype, Lexer::Token::...
function parseUntil (line 72) | void parseUntil(Lexer& lexer, Lexer::Token::Type type) {
function parseArray (line 83) | std::size_t parseArray(Lexer& lexer, Parser::Parse& result) {
function parseUniform (line 114) | void parseUniform(Lexer& lexer, const Lexer::Token& current, Parser::P...
function parseScope (line 135) | Parser::Locals parseScope(Lexer& lexer, Parser::Parse& result) {
function parseVSOut (line 178) | void parseVSOut(Lexer& lexer, const Lexer::Token& type, const Parser::...
function parseGlobal (line 192) | void parseGlobal(Lexer& lexer, const Lexer::Token& current, Parser::Pa...
function parseVersion (line 217) | void parseVersion(Lexer& lexer, const Lexer::Token& current, Parser::P...
function parseDefine (line 239) | void parseDefine(Lexer& lexer, Parser::Parse& result) {
function parsePreprocessor (line 257) | void parsePreprocessor(Lexer& lexer, const Lexer::Token& current, Pars...
function parseIdentifier (line 262) | void parseIdentifier(Lexer& lexer, const Lexer::Token& current, Parser...
function parseDatatype (line 278) | void parseDatatype(Lexer& lexer, const Lexer::Token& current, Parser::...
function parseStruct (line 284) | void parseStruct(Lexer& lexer, const Lexer::Token& current, Parser::Pa...
FILE: graphics/shader/parser.h
function namespace (line 9) | namespace P3D::Graphics {
FILE: graphics/shader/propertiesParser.cpp
type P3D::Graphics (line 6) | namespace P3D::Graphics {
function parseType (line 8) | std::optional<Property::Type> parseType(const Lexer& lexer, const Lexe...
function arity (line 32) | std::size_t arity(const Property::Type& type) {
function parseDefault (line 50) | std::optional<Property::Default> parseDefault(Lexer& lexer, const Lexe...
function parseProperty (line 86) | std::optional<Property> parseProperty(Lexer& lexer, const Lexer::Token...
FILE: graphics/shader/propertiesParser.h
function namespace (line 5) | namespace P3D::Graphics {
FILE: graphics/shader/shader.cpp
type P3D::Graphics (line 14) | namespace P3D::Graphics {
function GLID (line 105) | GLID Shader::compile(const Source& source) {
function GLID (line 161) | GLID Shader::compile(const std::string& common, const std::string& sou...
FILE: graphics/shader/shader.h
function namespace (line 6) | namespace P3D::Graphics {
FILE: graphics/shader/shaders.cpp
type P3D::Graphics (line 11) | namespace P3D::Graphics {
type Shaders (line 13) | namespace Shaders {
function onInit (line 19) | void onInit() {
function onClose (line 171) | void onClose() {
FILE: graphics/shader/shaders.h
function namespace (line 7) | namespace P3D::Graphics {
FILE: graphics/texture.cpp
type P3D::Graphics (line 11) | namespace P3D::Graphics {
function getChannelsFromFormat (line 19) | int getChannelsFromFormat(int format) {
function getFormatFromChannels (line 39) | int getFormatFromChannels(int channels) {
function Texture (line 55) | Texture Texture::load(const std::string& name) {
function Texture (line 131) | Texture& Texture::operator=(Texture&& other) {
FILE: graphics/texture.h
function namespace (line 6) | namespace P3D::Graphics {
FILE: tests/boundsTree2Tests.cpp
function shuffleTreeRecursive (line 17) | static void shuffleTreeRecursive(TreeTrunk& curTrunk, int curTrunkSize) {
function shuffleTree (line 39) | static void shuffleTree(BoundsTreePrototype& tree) {
function shuffleTree (line 44) | static void shuffleTree(BoundsTree<Boundable>& tree) {
function generateBoundsTreeBounds (line 48) | static BoundsTemplate<float> generateBoundsTreeBounds() {
function generateBoundsTreeItems (line 60) | static std::vector<BasicBounded> generateBoundsTreeItems(int size) {
function TEST_CASE (line 70) | TEST_CASE(testAddRemoveToBoundsTree) {
function groupsMatchTree (line 109) | static bool groupsMatchTree(const std::vector<std::vector<BasicBounded*>...
function mergeGroups (line 145) | static void mergeGroups(std::vector<std::vector<BasicBounded*>>& groups,...
function TEST_CASE (line 154) | TEST_CASE(testBoundsTreeGroupCreation) {
function createGroups (line 188) | static std::vector<std::vector<BasicBounded*>> createGroups(BoundsTree<B...
function TEST_CASE (line 222) | TEST_CASE(testBoundsTreeGroupMerging) {
function TEST_CASE_SLOW (line 249) | TEST_CASE_SLOW(testBoundsTreeGroupMergingSplitting) {
function TEST_CASE (line 324) | TEST_CASE(testForEachColission) {
function TEST_CASE (line 384) | TEST_CASE(testForEachColissionBetween) {
function TEST_CASE (line 425) | TEST_CASE(testUpdatePartBounds) {
function TEST_CASE (line 447) | TEST_CASE(testUpdateGroupBounds) {
function TEST_CASE (line 473) | TEST_CASE(testImproveStructureValidity) {
FILE: tests/compare.h
function tolerantEquals (line 57) | bool tolerantEquals(const P3D::Vector<Num1, Size>& first, const P3D::Vec...
function tolerantEquals (line 72) | bool tolerantEquals(const P3D::Matrix<Num1, Height, Width>& first, const...
function tolerantEquals (line 82) | bool tolerantEquals(const P3D::SymmetricMatrix<Num1, Size>& first, const...
function tolerantEquals (line 92) | bool tolerantEquals(const P3D::DiagonalMatrix<Num1, Size>& first, const ...
function tolerantEquals (line 186) | bool tolerantEquals(const P3D::TaylorExpansion<T, DerivationCount>& firs...
function tolerantEquals (line 191) | bool tolerantEquals(const P3D::FullTaylorExpansion<T, DerivationCount>& ...
function tolerantEquals (line 251) | bool tolerantEquals(const P3D::Matrix<T, Height, Width>& first, const P3...
function tolerantEquals (line 261) | bool tolerantEquals(const P3D::UnmanagedHorizontalFixedMatrix<T, Width>&...
function tolerantEquals (line 265) | bool tolerantEquals(const P3D::Matrix<T, Height, Width>& first, const P3...
function tolerantEquals (line 275) | bool tolerantEquals(const P3D::UnmanagedVerticalFixedMatrix<T, Height>& ...
function tolerantEquals (line 279) | bool tolerantEquals(const P3D::UnmanagedVerticalFixedMatrix<T, Size>& fi...
function tolerantEquals (line 289) | bool tolerantEquals(const P3D::UnmanagedHorizontalFixedMatrix<T, Size>& ...
FILE: tests/constraintTests.cpp
function TEST_CASE (line 26) | TEST_CASE(testMotionOfPhysicalSinglePart) {
function TEST_CASE (line 55) | TEST_CASE(testMotionOfPhysicalPartsBasic) {
function TEST_CASE (line 93) | TEST_CASE(testMotionOfPhysicalPartsRotation) {
function TEST_CASE (line 134) | TEST_CASE(testMotionOfPhysicalPartsBasicFixedConstraint) {
function TEST_CASE (line 172) | TEST_CASE(testMotionOfPhysicalPartsRotationFixedConstraint) {
function TEST_CASE (line 214) | TEST_CASE(testMotionOfPhysicalParts) {
function TEST_CASE (line 251) | TEST_CASE(testMotionOfPhysicalJointsBasic) {
function TEST_CASE (line 270) | TEST_CASE(testMotionOfPhysicalJointsRotation) {
function TEST_CASE (line 296) | TEST_CASE(testMotionOfPhysicalJoints) {
function TEST_CASE (line 322) | TEST_CASE(testFixedConstraintProperties) {
function TEST_CASE (line 346) | TEST_CASE(testApplyForceToFixedConstraint) {
function TEST_CASE (line 392) | TEST_CASE(testPlainAttachAndFixedConstraintIndistinguishable) {
function TEST_CASE (line 419) | TEST_CASE(testInternalMotionOfCenterOfMass) {
function haveSameMotorPhys (line 448) | static bool haveSameMotorPhys(const Part& first, const Part& second) {
function TEST_CASE (line 452) | TEST_CASE(attachPhysicalsNoLayers) {
function areInSameGroup (line 465) | bool areInSameGroup(const Part& a, const Part& b) {
function pairwiseCorrectlyGrouped (line 469) | static bool pairwiseCorrectlyGrouped(const std::vector<Part>& la, const ...
function TEST_CASE (line 482) | TEST_CASE(attachPhysicalsWithLayers) {
FILE: tests/ecsTests.cpp
type P3D (line 7) | namespace P3D {
function TEST_CASE (line 8) | TEST_CASE(idGeneration) {
function TEST_CASE (line 19) | TEST_CASE(componentGeneration) {
function TEST_CASE (line 35) | TEST_CASE(componentAccess) {
function TEST_CASE (line 53) | TEST_CASE(viewTest) {
function TEST_CASE (line 89) | TEST_CASE(entityParent) {
function TEST_CASE (line 102) | TEST_CASE(getChildren) {
function TEST_CASE (line 120) | TEST_CASE(getFromView) {
FILE: tests/estimateMotion.cpp
type P3D (line 6) | namespace P3D {
function Vec3 (line 7) | Vec3 getVelocityBySimulation(const Motion& m, const Vec3& point, doubl...
function Motion (line 13) | Motion getMotionBySimulation(const Motion& m, const Vec3& point, doubl...
function TranslationalMotion (line 37) | TranslationalMotion estimateMotion(const Vec3& startPos, const Vec3& m...
function TranslationalMotion (line 48) | TranslationalMotion estimateMotion(const Position& startPos, const Pos...
function Vec3 (line 63) | static Vec3 getRotationVecFor(const Rotation& firstRot, const Rotation...
function Vec3 (line 69) | Vec3 getRotationVelFor(const Rotation& before, const Rotation& after, ...
function Motion (line 75) | Motion estimateMotion(const CFrame& step1, const CFrame& step2, const ...
function Motion (line 88) | Motion estimateMotion(const GlobalCFrame& step1, const GlobalCFrame& s...
function CFrame (line 102) | CFrame simulateForTime(const Motion& motion, const CFrame& startingCFr...
FILE: tests/estimateMotion.h
function namespace (line 10) | namespace P3D {
FILE: tests/estimationTests.cpp
function TEST_CASE_SLOW (line 10) | TEST_CASE_SLOW(volumeApproximation) {
function TEST_CASE_SLOW (line 42) | TEST_CASE_SLOW(centerOfMassApproximation) {
function TEST_CASE_SLOW (line 76) | TEST_CASE_SLOW(inertiaApproximation) {
FILE: tests/generators.cpp
type P3D (line 11) | namespace P3D {
function generateInt (line 14) | int generateInt(int max) {
function generateSize_t (line 17) | size_t generateSize_t(size_t max) {
function generateDouble (line 20) | double generateDouble() {
function generateFloat (line 23) | float generateFloat() {
function generateDouble (line 26) | double generateDouble(double min, double max) {
function generateFloat (line 29) | float generateFloat(float min, float max) {
function generateBool (line 33) | bool generateBool() {
function Shape (line 37) | Shape generateShape() {
function Polyhedron (line 41) | Polyhedron generateConvexPolyhedron() {
function Triangle (line 64) | static Triangle finishTriangle(int maxIndex, int firstIndex) {
function Triangle (line 78) | Triangle generateTriangle(int maxIndex) {
function TriangleMesh (line 84) | TriangleMesh generateTriangleMesh() {
function generatePositionf (line 104) | PositionTemplate<float> generatePositionf() {
function Position (line 108) | Position generatePosition() {
function generateBoundsf (line 112) | BoundsTemplate<float> generateBoundsf() {
function Bounds (line 119) | Bounds generateBounds() {
function DiagonalMat3 (line 126) | DiagonalMat3 generateDiagonalMatrix() {
function Rotation (line 130) | Rotation generateRotation() {
function CFrame (line 134) | CFrame generateCFrame() {
function GlobalCFrame (line 138) | GlobalCFrame generateGlobalCFrame() {
function TranslationalMotion (line 143) | TranslationalMotion generateTranslationalMotion() {
function RotationalMotion (line 146) | RotationalMotion generateRotationalMotion() {
function Motion (line 149) | Motion generateMotion() {
function RelativeMotion (line 152) | RelativeMotion generateRelativeMotion() {
function PartProperties (line 157) | PartProperties generatePartProperties() {
function Part (line 160) | Part generatePart() {
function Part (line 164) | Part generatePart(Part& attachTo) {
function Part (line 168) | Part generatePart(Part& attachTo, HardConstraint* constraint) {
function HardConstraint (line 172) | HardConstraint* generateHardConstraint() {
function generateAttachment (line 176) | void generateAttachment(Part& first, Part& second) {
function generateMotorizedPhysicalParts (line 184) | std::vector<Part> generateMotorizedPhysicalParts() {
function generateLayerAssignment (line 200) | void generateLayerAssignment(std::vector<Part>& parts, WorldPrototype&...
FILE: tests/generators.h
function namespace (line 30) | namespace P3D {
function generate (line 38) | inline double generate() {
function generate (line 43) | inline float generate() {
function generate (line 47) | inline int8_t generate() {
function generate (line 51) | inline uint8_t generate() {
function generate (line 55) | inline int16_t generate() {
function generate (line 59) | inline uint16_t generate() {
function generate (line 63) | inline int32_t generate() {
function generate (line 67) | inline uint32_t generate() {
function generate (line 71) | inline int64_t generate() {
function generate (line 75) | inline uint64_t generate() {
function Vec3 (line 111) | inline Vec3 generateVec3() { return generateVector<double, 3>(); }
function Vec3f (line 112) | inline Vec3f generateVec3f() { return generateVector<float, 3>(); }
FILE: tests/geometryTests.cpp
function isDiagonalTolerant (line 27) | bool isDiagonalTolerant(const Matrix<T, Size, Size>& m, Tol tolerance) {
function isDiagonalTolerant (line 39) | bool isDiagonalTolerant(const SymmetricMatrix<T, Size>& m, Tol tolerance) {
function isSymmetricTolerant (line 51) | bool isSymmetricTolerant(const Matrix<T, Size, Size>& m, Tol tolerance) {
function TEST_CASE (line 65) | TEST_CASE(shapeVolume) {
function TEST_CASE (line 76) | TEST_CASE(shapeCenterOfMass) {
function TEST_CASE (line 103) | TEST_CASE(shapeInertiaRotationInvariance) {
function TEST_CASE (line 135) | TEST_CASE(shapeInertiaEigenValueInvariance) {
function TEST_CASE (line 151) | TEST_CASE(testRayIntersection) {
function TEST_CASE (line 158) | TEST_CASE(testGetFurthestPointInDirection) {
function TEST_CASE (line 164) | TEST_CASE(testCornerShape) {
function TEST_CASE (line 180) | TEST_CASE(testWedgeShape) {
function TEST_CASE (line 196) | TEST_CASE(testTriangleMeshOptimizedGetBounds) {
function TEST_CASE (line 215) | TEST_CASE(testTriangleMeshOptimizedGetBoundsRotated) {
function TEST_CASE (line 235) | TEST_CASE(testTriangleMeshOptimizedFurthestIndexInDirection) {
function TEST_CASE (line 265) | TEST_CASE(testTriangleMeshOptimizedFurthestInDirection) {
FILE: tests/guiTests.cpp
function TEST_CASE (line 16) | TEST_CASE(transformationTest) {
FILE: tests/indexedShapeTests.cpp
function TEST_CASE (line 13) | TEST_CASE(testIndexedShape) {
function TEST_CASE (line 26) | TEST_CASE(buildShape) {
function TEST_CASE (line 40) | TEST_CASE(buildConvexShape) {
FILE: tests/inertiaTests.cpp
function TEST_CASE (line 18) | TEST_CASE(movedInertialMatrixForBox) {
function TEST_CASE (line 28) | TEST_CASE(movedInertialMatrixForDifficuiltPart) {
function TEST_CASE (line 38) | TEST_CASE(inertiaTranslationDerivatives) {
function TEST_CASE (line 56) | TEST_CASE(inertiaRotationDerivatives) {
function TEST_CASE (line 73) | TEST_CASE(inertiaTransformationDerivatives) {
function TEST_CASE (line 97) | TEST_CASE(inertiaTransformationDerivativesForOffsetCenterOfMass) {
function TEST_CASE (line 126) | TEST_CASE(premadeAngularMomentum) {
function TEST_CASE (line 157) | TEST_CASE(translatedAngularMomentum) {
FILE: tests/jointTests.cpp
function TEST_CASE (line 25) | TEST_CASE(testConstraintMatrixPack) {
function TEST_CASE (line 44) | TEST_CASE(testBallConstraintMatrices) {
function TEST_CASE (line 75) | TEST_CASE(testBallConstraintSymmetric) {
FILE: tests/lexerTests.cpp
function TEST_CASE (line 50) | TEST_CASE(lexVersionPreprocessor) {
function TEST_CASE (line 67) | TEST_CASE(lexShader) {
function TEST_CASE (line 79) | TEST_CASE(parseShader) {
FILE: tests/mathTests.cpp
function TEST_CASE (line 27) | TEST_CASE(subMatrixOperations) {
function TEST_CASE (line 58) | TEST_CASE(determinant) {
function TEST_CASE (line 82) | TEST_CASE(matrixInverse2) {
function TEST_CASE (line 92) | TEST_CASE(matrixInverse3) {
function TEST_CASE (line 107) | TEST_CASE(matrixInverse4) {
function TEST_CASE (line 122) | TEST_CASE(cframeInverse) {
function TEST_CASE (line 135) | TEST_CASE(matrixAssociativity) {
function TEST_CASE (line 159) | TEST_CASE(cframeAssociativity) {
function TEST_CASE (line 171) | TEST_CASE(fromEuler) {
function TEST_CASE (line 175) | TEST_CASE(crossProduct) {
function TEST_CASE (line 193) | TEST_CASE(eigenDecomposition) {
function TEST_CASE (line 213) | TEST_CASE(largeMatrixVectorSolve) {
function TEST_CASE (line 238) | TEST_CASE(testTaylorExpansion) {
function TEST_CASE (line 253) | TEST_CASE(testSinTaylorExpansion) {
function TEST_CASE (line 272) | TEST_CASE(testMultiplicationDerivatives) {
function TEST_CASE (line 297) | TEST_CASE(testCrossProductEquivalent) {
function TEST_CASE (line 304) | TEST_CASE(testSkewSymmetricValid) {
function TEST_CASE (line 313) | TEST_CASE(testSkewSymmetricDerivatives) {
function TEST_CASE (line 331) | TEST_CASE(testSimulation) {
function TEST_CASE (line 343) | TEST_CASE(testRotationDerivs) {
function TEST_CASE (line 364) | TEST_CASE(testFromRotationVec) {
function TEST_CASE (line 390) | TEST_CASE(quaternionBasicRotation) {
function TEST_CASE (line 400) | TEST_CASE(quaternionRotationShorthand) {
function TEST_CASE (line 408) | TEST_CASE(quaternionFromRotationVecToRotationMatrix) {
function TEST_CASE (line 419) | TEST_CASE(interchanceQuaternionAndMatrix) {
function TEST_CASE (line 433) | TEST_CASE(testFixCastToInt) {
FILE: tests/motionTests.cpp
function TEST_CASE (line 23) | TEST_CASE(testBasicMotion) {
function TEST_CASE (line 33) | TEST_CASE(testAdvancedMotion) {
function TEST_CASE (line 45) | TEST_CASE(testMotionOfMotorConstraintCorrect) {
function TEST_CASE (line 61) | TEST_CASE(testMotionOfPistonConstraintCorrect) {
function TEST_CASE (line 77) | TEST_CASE(testPistonConstraint) {
function TEST_CASE (line 93) | TEST_CASE(testExtendBegin) {
function TEST_CASE (line 103) | TEST_CASE(testExtendEnd) {
function TEST_CASE (line 113) | TEST_CASE(testExtendingRelativeMotionCVecCommutes) {
function TEST_CASE (line 123) | TEST_CASE(testExtendingRelativeMotionCFrameCommutes) {
function TEST_CASE (line 133) | TEST_CASE(testExtendingRelativeMotionVecCorrect) {
function TEST_CASE (line 147) | TEST_CASE(testExtendingRelativeMotionCFrameCorrect) {
function TEST_CASE (line 163) | TEST_CASE(testJoiningRelativeMotionCorrect) {
function TEST_CASE (line 180) | TEST_CASE(testComplexRelativeMotionAssociative) {
function TEST_CASE (line 189) | TEST_CASE(testReducedRelativeMotionAssociative) {
function TEST_CASE (line 206) | TEST_CASE(testSimulateRelativeMotion) {
function TEST_CASE (line 236) | TEST_CASE(testSimulateRelativeToRelativeMotion) {
FILE: tests/physicalStructureTests.cpp
function CFrame (line 18) | static CFrame cf() {
function Part (line 22) | static Part* createPart() {
function TEST_CASE (line 26) | TEST_CASE(testBasicCreateDestroy) {
function TEST_CASE (line 32) | TEST_CASE(testManyAttachBasic) {
function TEST_CASE (line 54) | TEST_CASE(testManualDetach) {
function TEST_CASE (line 82) | TEST_CASE(testManyAttachComplex) {
function TEST_CASE (line 119) | TEST_CASE(testBasicMakeMainPhysical) {
function TEST_CASE (line 145) | TEST_CASE(testAdvancedMakeMainPhysical) {
function TEST_CASE (line 196) | TEST_CASE(testAttachConnectedPhysicalToConnectedPhysical) {
FILE: tests/physicsTests.cpp
function TEST_CASE_SLOW (line 32) | TEST_CASE_SLOW(positionInvariance) {
function TEST_CASE_SLOW (line 62) | TEST_CASE_SLOW(rotationInvariance) {
function TEST_CASE (line 90) | TEST_CASE(applyForceToRotate) {
function TEST_CASE (line 102) | TEST_CASE(momentToAngularVelocity) {
function TEST_CASE (line 116) | TEST_CASE(rotationImpulse) {
function TEST_CASE (line 172) | TEST_CASE(impulseTest) {
function TEST_CASE (line 187) | TEST_CASE(testPointAccelMatrixImpulse) {
function TEST_CASE (line 203) | TEST_CASE(inelasticColission) {
function TEST_CASE (line 249) | TEST_CASE(inelasticColission2) {
function TEST_CASE (line 303) | TEST_CASE(testChangeInertialBasis) {
function TEST_CASE (line 313) | TEST_CASE(testMultiPartPhysicalSimple) {
function TEST_CASE (line 334) | TEST_CASE(testMultiPartPhysicalRotated) {
function TEST_CASE (line 353) | TEST_CASE(testShapeNativeScaling) {
function TEST_CASE (line 364) | TEST_CASE(testPhysicalInertiaDerivatives) {
function TEST_CASE (line 407) | TEST_CASE(testCenterOfMassKept) {
function TEST_CASE (line 424) | TEST_CASE(testBasicAngularMomentum) {
function TEST_CASE (line 443) | TEST_CASE(testBasicAngularMomentumTurned) {
function TEST_CASE (line 463) | TEST_CASE(testFixedConstraintAngularMomentum) {
function Position (line 510) | static Position getTotalCenterOfMassOfPhysical(const MotorizedPhysical* ...
function Vec3 (line 524) | static Vec3 getTotalMotionOfCenterOfMassOfPhysical(const MotorizedPhysic...
function SymmetricMat3 (line 540) | static SymmetricMat3 getTotalInertiaOfPhysical(const MotorizedPhysical* ...
function Vec3 (line 560) | static Vec3 getTotalAngularMomentumOfPhysical(const MotorizedPhysical* m...
function producePhysical (line 579) | std::vector<Part> producePhysical() {
function produceMotorizedPhysical (line 598) | std::vector<Part> produceMotorizedPhysical() {
type FullGlobalDiagnostic (line 625) | struct FullGlobalDiagnostic {
function tolerantEquals (line 635) | bool tolerantEquals(const FullGlobalDiagnostic& first, const FullGlobalD...
function FullGlobalDiagnostic (line 666) | static FullGlobalDiagnostic doDiagnostic(MotorizedPhysical* p) {
function FullGlobalDiagnostic (line 685) | static FullGlobalDiagnostic runDiagnosticForCFrame(MotorizedPhysical* p,...
function TEST_CASE (line 700) | TEST_CASE(basicFullRotationSymmetryInvariance) {
function TEST_CASE (line 735) | TEST_CASE(angularMomentumOverLocalToGlobal) {
function TEST_CASE (line 763) | TEST_CASE(hardConstrainedFullRotationFollowsCorrectly) {
function TEST_CASE (line 798) | TEST_CASE(basicAngularMomentumOfSinglePart) {
function TEST_CASE (line 813) | TEST_CASE(motorizedPhysicalAngularMomentum) {
function TEST_CASE (line 823) | TEST_CASE(physicalTotalAngularMomentum) {
function TEST_CASE (line 834) | TEST_CASE(basicMotorizedPhysicalTotalAngularMomentum) {
function TEST_CASE (line 863) | TEST_CASE(totalInertiaOfPhysical) {
function TEST_CASE (line 872) | TEST_CASE(totalInertiaOfBasicMotorizedPhysical) {
function TEST_CASE (line 899) | TEST_CASE(totalCenterOfMassOfPhysical) {
function TEST_CASE (line 906) | TEST_CASE(totalCenterOfMassOfMotorizedPhysical) {
function TEST_CASE (line 913) | TEST_CASE(totalVelocityOfCenterOfMassOfPhysical) {
function TEST_CASE (line 922) | TEST_CASE(totalVelocityOfCenterOfMassOfMotorizedPhysical) {
function TEST_CASE (line 931) | TEST_CASE(totalInertiaOfMotorizedPhysical) {
function TEST_CASE (line 940) | TEST_CASE(motorizedPhysicalTotalAngularMomentum) {
function TEST_CASE (line 951) | TEST_CASE(conservationOfAngularMomentum) {
function TEST_CASE (line 967) | TEST_CASE(conservationOfCenterOfMass) {
function TEST_CASE (line 983) | TEST_CASE(angularMomentumVelocityInvariance) {
function TEST_CASE (line 1002) | TEST_CASE(setVelocity) {
FILE: tests/randomValues.h
function namespace (line 17) | namespace P3D {
FILE: tests/rotationTests.cpp
function TEST_CASE (line 22) | TEST_CASE(testFromRotationVecInvertsFromRotationMatrix) {
function TEST_CASE (line 45) | TEST_CASE(rotationGlobalToLocalInvertsLocalToGlobal) {
function TEST_CASE (line 67) | TEST_CASE(rotationGlobalToLocalMatrixIdentity) {
function TEST_CASE (line 83) | TEST_CASE(rotationAssociative) {
function TEST_CASE (line 104) | TEST_CASE(rotXrotYrotZ) {
function TEST_CASE (line 123) | TEST_CASE(faceDirection) {
function TEST_CASE (line 134) | TEST_CASE(rotationMatrix) {
function TEST_CASE (line 143) | TEST_CASE(rotationQuaternionNegative) {
function TEST_CASE (line 157) | TEST_CASE(quaternionFromRotVecInverse) {
function TEST_CASE (line 165) | TEST_CASE(rotationImplementationIdenticalFromEulerAngles) {
function TEST_CASE (line 176) | TEST_CASE(rotationImplementationIdenticalLocalGlobal) {
function TEST_CASE (line 205) | TEST_CASE(rotationImplementationIdenticalInverse) {
function TEST_CASE (line 214) | TEST_CASE(rotationImplementationIdenticalFaceMatrices) {
function TEST_CASE (line 225) | TEST_CASE(rotationImplementationIdenticalGetXYZ) {
FILE: tests/simulation.h
function namespace (line 13) | namespace P3D {
function else (line 79) | struct Recurse {
FILE: tests/testFrameworkConsistencyTests.cpp
function TEST_CASE (line 16) | TEST_CASE(testEstimateDerivativesOfComputeOverTime) {
FILE: tests/testValues.cpp
type P3D (line 5) | namespace P3D {
FILE: tests/testValues.h
function namespace (line 7) | namespace P3D {
FILE: tests/testsMain.cpp
function resetLog (line 39) | static void resetLog() {
function logf (line 46) | void logf(const char* format, ...) {
function printDeltaTime (line 56) | static void printDeltaTime(time_point<system_clock> startTime, TerminalC...
function ifstream (line 62) | static ifstream getFileStream(const char* fileName) {
function printFileSlice (line 80) | static void printFileSlice(const char* fileName, int line) {
function dumpLog (line 113) | static void dumpLog() {
type TestResult (line 117) | enum class TestResult {
type TestFlags (line 124) | struct TestFlags {
class Test (line 131) | class Test {
method Test (line 139) | Test() :
method Test (line 141) | Test(const char* filePath, const char* funcName, void(*testFunc)(), Te...
method TestResult (line 148) | TestResult runNoErrorChecking(TestFlags flags, time_point<system_clock...
method TestResult (line 181) | TestResult run(TestFlags flags) {
function initConsole (line 236) | static void initConsole() {
function initConsole (line 246) | static void initConsole() {}
function isCoveredBy (line 249) | static bool isCoveredBy(Test& test, const std::vector<std::string>& filt...
function runTests (line 261) | static void runTests(const std::vector<std::string>& filter, TestFlags f...
function TestFlags (line 288) | TestFlags getTestFlags(const Util::ParsedArgs& cmdArgs) {
function main (line 301) | int main(int argc, const char** argv) {
function logAssertError (line 331) | static void logAssertError(string text) {
FILE: tests/testsMain.h
function class (line 7) | class TestInterface {
function TestType (line 19) | enum class TestType {
type AssertBuilder (line 124) | struct AssertBuilder {
FILE: util/cmdParser.h
function namespace (line 6) | namespace Util {
FILE: util/fileUtils.cpp
type stat (line 12) | struct stat
type Util (line 49) | namespace Util {
function warnIfFileExists (line 51) | void warnIfFileExists(const std::string& fileName) {
function parseFile (line 57) | std::string parseFile(const std::string& path) {
FILE: util/fileUtils.h
function namespace (line 5) | namespace Util {
FILE: util/iteratorUtils.h
type iterator_end (line 3) | struct iterator_end {}
function IteratorEnd (line 23) | bool operator!=(IteratorEnd) const {
function IteratorEnd (line 90) | bool operator!=(IteratorEnd) const {
function iterator (line 98) | bool operator==(Iterator iterator) const {
function IteratorEnd (line 126) | bool operator!=(IteratorEnd) const {
function iterator (line 134) | bool operator==(Iterator iterator) const {
FILE: util/log.cpp
type Log (line 9) | namespace Log {
function logTogether (line 20) | static void logTogether(const char* message, va_list args) {
function init (line 31) | void init(const char* logFileName) {
function stop (line 38) | void stop() {
function topSubject (line 43) | std::string topSubject() {
function emptySubject (line 72) | bool emptySubject() {
function setLogLevel (line 76) | void setLogLevel(Level level) {
function Level (line 80) | Level getLogLevel() {
function printSubject (line 84) | static void printSubject(std::string subject) {
function addSubjectIfNeeded (line 93) | static void addSubjectIfNeeded() {
function setDelimiter (line 98) | void setDelimiter(std::string delimiter) {
function debug (line 102) | void debug(std::string format, ...) {
function info (line 112) | void info(std::string format, ...) {
function warn (line 122) | void warn(std::string format, ...) {
function error (line 132) | void error(std::string format, ...) {
function fatal (line 142) | void fatal(std::string format, ...) {
function print (line 152) | void print(std::string format, ...) {
function print (line 157) | void print(TerminalColorPair color, std::string format, ...) {
FILE: util/log.h
function TerminalColorPair (line 18) | const TerminalColorPair SUBJECT { TerminalColor::MAGENTA, TerminalColor:...
function Level (line 21) | enum class Level : char {
FILE: util/parseCPUIDArgs.h
function namespace (line 9) | namespace Util {
FILE: util/properties.cpp
type Util (line 8) | namespace Util {
type PropertiesParser (line 41) | namespace PropertiesParser {
function Properties (line 42) | Properties read(const std::string& file) {
function write (line 77) | void write(const std::string& filename, Properties& properties) {
FILE: util/properties.h
function namespace (line 7) | namespace Util {
FILE: util/resource/resource.h
type class (line 26) | enum class
function virtual (line 47) | virtual std::string getTypeName() const = 0;
function ResourceType (line 64) | inline static ResourceType getStaticType() { return ResourceType::type; }
FILE: util/resource/resourceDescriptor.h
type ResourceDescriptor (line 6) | struct ResourceDescriptor {
type ResourceDescriptor (line 12) | struct ResourceDescriptor {
FILE: util/resource/resourceLoader.cpp
class ResourceLoader (line 11) | class ResourceLoader {
type Parameters (line 13) | struct Parameters {
method ResourceLoader (line 25) | ResourceLoader(int id, const std::string& type) {
method getResourceString (line 33) | std::string getResourceString() const {
function getResourceAsString (line 41) | std::string getResourceAsString(const ResourceDescriptor* list, int id) {
function getResourceAsString (line 52) | std::string getResourceAsString(const ResourceDescriptor* list, int id) {
FILE: util/resource/resourceLoader.h
type ResourceDescriptor (line 5) | struct ResourceDescriptor
FILE: util/resource/resourceManager.h
function class (line 12) | class ResourceManager {
FILE: util/stringUtil.cpp
type Util (line 7) | namespace Util {
function demangle_win (line 9) | static std::string demangle_win(const std::string& fullName) {
function demangle (line 29) | std::string demangle(const std::string& fullName) {
function demangle (line 48) | std::string demangle(const std::string& fullName) {
function demangle (line 54) | std::string demangle(const std::string& fullName) {
function decamel (line 60) | std::string decamel(const std::string& string) {
function split (line 73) | std::vector<std::string> split(const std::string& string, char splitte...
function split_view (line 91) | std::vector<std::string_view> split_view(const std::string_view& strin...
function startsWith (line 109) | bool startsWith(const std::string& string, const std::string& prefix) {
function endsWith (line 124) | bool endsWith(const std::string& string, const std::string& suffix) {
function until (line 139) | std::string until(const std::string& string, char end) {
function ltrim (line 149) | std::string ltrim(const std::string& string) {
function rtrim (line 160) | std::string rtrim(const std::string& string) {
function trim (line 171) | std::string trim(const std::string& string) {
FILE: util/stringUtil.h
function namespace (line 8) | namespace Util {
FILE: util/systemVariables.h
type SystemVariables (line 5) | struct SystemVariables {
FILE: util/terminalColor.cpp
function setColor (line 3) | void setColor(TerminalColor foreground) {
function setColor (line 7) | void setColor(TerminalColorPair color) {
function setColor (line 15) | void setColor(TerminalColor foreground, TerminalColor background) {
function cvtWinColorToUnixColor (line 22) | static char cvtWinColorToUnixColor(int winColor){
function setColor (line 35) | void setColor(TerminalColor foreground, TerminalColor background) {
FILE: util/terminalColor.h
function TerminalColor (line 3) | enum class TerminalColor {
FILE: util/valueCycle.cpp
type Util (line 3) | namespace Util {
function linear (line 5) | float linear(float t) {
function smoothstep (line 9) | float smoothstep(float t) {
function easeInQuad (line 13) | float easeInQuad(float t) {
function easeOutQuad (line 17) | float easeOutQuad(float t) {
function easeInOutQuad (line 21) | float easeInOutQuad(float t) {
function easeInCubic (line 25) | float easeInCubic(float t) {
function easeOutCubic (line 29) | float easeOutCubic(float t) {
function easeInOuCubic (line 33) | float easeInOuCubic(float t) {
FILE: util/valueCycle.h
function namespace (line 7) | namespace Util {
Condensed preview — 548 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,326K chars).
[
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 535,
"preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the b"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 595,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your fea"
},
{
"path": ".github/workflows/msvcBuild.yml",
"chars": 289,
"preview": "name: MSVC\non:\n push:\n branches: [ master ]\n pull_request:\n branches: [ master ]\n\njobs:\n buildMSVC:\n\n runs-o"
},
{
"path": ".github/workflows/ubuntuBuild.yml",
"chars": 300,
"preview": "name: Ubuntu\non:\n push:\n branches: [ master ]\n pull_request:\n branches: [ master ]\n\njobs:\n buildUbuntu:\n\n ru"
},
{
"path": ".gitignore",
"chars": 465,
"preview": "\n# Files possibly generated by Physics3D\nres/.properties\nimgui.ini\nres/imgui.ini\n*.parts\n*.nativeParts\n*.world\n*.obj\n*.b"
},
{
"path": "CMakeLists.txt",
"chars": 7909,
"preview": "cmake_minimum_required(VERSION 3.10)\n\nproject(Physics3D-application VERSION 1.0)\n\nmessage(STATUS \"Build type: ${CMAKE_BU"
},
{
"path": "LICENSE.md",
"chars": 1071,
"preview": "MIT License\n\nCopyright (c) 2018 ThePhysicsGuys\n\nPermission is hereby granted, free of charge, to any person obtaining a "
},
{
"path": "Physics3D/CMakeLists.txt",
"chars": 3037,
"preview": "cmake_minimum_required(VERSION 3.10)\n\nproject(Physics3D VERSION 0.9)\n\n\nset(CMAKE_CXX_STANDARD 23)\nset(CMAKE_CXX_STANDARD"
},
{
"path": "Physics3D/Physics3D.vcxproj",
"chars": 16251,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.microso"
},
{
"path": "Physics3D/boundstree/boundsTree.cpp",
"chars": 37962,
"preview": "#include \"boundsTree.h\"\n\n\n#include \"../datastructures/aligned_alloc.h\"\n\nnamespace P3D {\n// naive implementation, to be o"
},
{
"path": "Physics3D/boundstree/boundsTree.h",
"chars": 42918,
"preview": "#pragma once\n\n#include \"../math/fix.h\"\n#include \"../math/position.h\"\n#include \"../math/bounds.h\"\n#include \"../datastruct"
},
{
"path": "Physics3D/boundstree/boundsTreeAVX.cpp",
"chars": 2368,
"preview": "#include \"boundsTree.h\" \n\n#include \"../datastructures/alignedPtr.h\"\n#include <immintrin.h>\n\nnamespace P3D {\n\nOverlapMatr"
},
{
"path": "Physics3D/boundstree/boundsTreeSSE.cpp",
"chars": 2298,
"preview": "#include \"boundsTree.h\" \n\n#include \"../datastructures/alignedPtr.h\"\n#include <immintrin.h>\n \nnamespace P3D {\n\nOverlapMat"
},
{
"path": "Physics3D/boundstree/filters/outOfBoundsFilter.h",
"chars": 584,
"preview": "#pragma once\n\n#include \"../../math/bounds.h\"\n#include \"../boundsTree.h\"\n#include \"../../part.h\"\n\nnamespace P3D {\nstruct "
},
{
"path": "Physics3D/boundstree/filters/rayIntersectsBoundsFilter.h",
"chars": 628,
"preview": "#pragma once\n\n#include \"../../math/bounds.h\"\n#include \"../../math/ray.h\"\n#include \"../../part.h\"\n#include \"../boundsTree"
},
{
"path": "Physics3D/boundstree/filters/visibilityFilter.cpp",
"chars": 4124,
"preview": "#include \"visibilityFilter.h\"\n\n#include \"../../math/linalg/trigonometry.h\"\n#include \"../../math/position.h\"\n#include \".."
},
{
"path": "Physics3D/boundstree/filters/visibilityFilter.h",
"chars": 3215,
"preview": "#pragma once\n\n#include \"../../math/linalg/vec.h\"\n#include \"../../math/bounds.h\"\n#include \"../../part.h\"\n\nnamespace P3D {"
},
{
"path": "Physics3D/colissionBuffer.h",
"chars": 729,
"preview": "#pragma once\n\n#include <vector>\n\nnamespace P3D {\nstruct Colission {\n\tPart* p1;\n\tPart* p2;\n\tPosition intersection;\n\tVec3 "
},
{
"path": "Physics3D/constraints/ballConstraint.cpp",
"chars": 1748,
"preview": "#include \"ballConstraint.h\"\n#include \"constraintImpl.h\"\n\nnamespace P3D {\nint BallConstraint::maxNumberOfParameters() con"
},
{
"path": "Physics3D/constraints/ballConstraint.h",
"chars": 493,
"preview": "#pragma once\n\n#include \"../math/linalg/vec.h\"\n#include \"constraint.h\"\n\nnamespace P3D {\nstruct BallConstraint : public Co"
},
{
"path": "Physics3D/constraints/barConstraint.cpp",
"chars": 1906,
"preview": "#include \"barConstraint.h\"\n#include \"constraintImpl.h\"\n\nnamespace P3D {\nint BarConstraint::maxNumberOfParameters() const"
},
{
"path": "Physics3D/constraints/barConstraint.h",
"chars": 551,
"preview": "#pragma once\n\n\n#include \"../math/linalg/vec.h\"\n#include \"constraint.h\"\n\nnamespace P3D {\nstruct BarConstraint : public Co"
},
{
"path": "Physics3D/constraints/constraint.cpp",
"chars": 72,
"preview": "#include \"constraint.h\"\n\nnamespace P3D {\nConstraint::~Constraint() {}\n}\n"
},
{
"path": "Physics3D/constraints/constraint.h",
"chars": 320,
"preview": "#pragma once\n\nnamespace P3D {\nclass ConstraintMatrixPack;\nstruct PhysicalInfo;\nstruct Constraint {\n\tvirtual int maxNumbe"
},
{
"path": "Physics3D/constraints/constraintGroup.cpp",
"chars": 7637,
"preview": "#include \"constraintGroup.h\"\n\n#include \"constraintImpl.h\"\n\n#include \"../math/linalg/largeMatrix.h\"\n#include \"../math/lin"
},
{
"path": "Physics3D/constraints/constraintGroup.h",
"chars": 745,
"preview": "#pragma once\n\n#include <vector>\n#include \"constraint.h\"\n\nnamespace P3D {\nclass Physical;\nclass Part;\n\nclass PhysicalCons"
},
{
"path": "Physics3D/constraints/constraintImpl.h",
"chars": 2971,
"preview": "#pragma once\n\n#include \"constraint.h\"\n\n#include \"../math/linalg/mat.h\"\n#include \"../math/linalg/largeMatrix.h\"\n#include "
},
{
"path": "Physics3D/constraints/hingeConstraint.cpp",
"chars": 2531,
"preview": "#include \"hingeConstraint.h\"\n#include \"constraintImpl.h\"\n\nnamespace P3D {\nint HingeConstraint::maxNumberOfParameters() c"
},
{
"path": "Physics3D/constraints/hingeConstraint.h",
"chars": 574,
"preview": "#pragma once\n\n#include \"../math/linalg/vec.h\"\n#include \"constraint.h\"\n\nnamespace P3D {\nstruct HingeConstraint : public C"
},
{
"path": "Physics3D/datastructures/alignedPtr.h",
"chars": 2123,
"preview": "#pragma once\n\n#include <utility>\n#include <cstddef>\n\n#include \"aligned_alloc.h\"\n\nnamespace P3D {\ntemplate<typename T>\ncl"
},
{
"path": "Physics3D/datastructures/aligned_alloc.cpp",
"chars": 337,
"preview": "#include \"aligned_alloc.h\"\n\n#include <malloc.h>\n#include <stdlib.h>\n\nnamespace P3D {\nvoid* aligned_malloc(size_t size, s"
},
{
"path": "Physics3D/datastructures/aligned_alloc.h",
"chars": 142,
"preview": "#pragma once\n\n#include <cstddef>\n\nnamespace P3D {\nvoid* aligned_malloc(std::size_t size, std::size_t align);\nvoid aligne"
},
{
"path": "Physics3D/datastructures/buffers.h",
"chars": 8785,
"preview": "#pragma once\n\n#include <assert.h>\n\n#include \"iteratorEnd.h\"\n\nnamespace P3D {\ninline unsigned long long nextPowerOf2(unsi"
},
{
"path": "Physics3D/datastructures/compactPtrDataPair.h",
"chars": 5172,
"preview": "#pragma once\n\n#include <cstddef> \n#include <assert.h>\n\n/*\n\tStores a little extra data in the lower bits of the given ptr"
},
{
"path": "Physics3D/datastructures/iteratorEnd.h",
"chars": 54,
"preview": "#pragma once\nnamespace P3D {\nstruct IteratorEnd {};\n};"
},
{
"path": "Physics3D/datastructures/iteratorFactory.h",
"chars": 855,
"preview": "#pragma once\n#include <utility>\n#include \"iteratorEnd.h\"\n\nnamespace P3D {\ntemplate<typename BeginType, typename EndType "
},
{
"path": "Physics3D/datastructures/monotonicTree.h",
"chars": 2189,
"preview": "#pragma once\n\n#include <utility>\n#include <cstddef>\n#include <assert.h>\n\n#include \"unmanagedArray.h\"\n\nnamespace P3D {\nte"
},
{
"path": "Physics3D/datastructures/parallelArray.h",
"chars": 1855,
"preview": "#pragma once\n\n#include <cstddef>\n\nnamespace P3D {\ntemplate<typename T, std::size_t C>\nstruct ParallelArray {\n\tT values[C"
},
{
"path": "Physics3D/datastructures/sharedArray.h",
"chars": 2066,
"preview": "#pragma once\n\nnamespace P3D {\ntemplate <typename T>\nclass SharedArrayPtr {\n\tT* ptr;\n\tsize_t* refCount;\n\n\tinline SharedAr"
},
{
"path": "Physics3D/datastructures/smartPointers.h",
"chars": 4717,
"preview": "#pragma once\n\n#include <memory>\n#include <atomic>\n\nnamespace P3D {\n\nstruct RC {\n\tstd::size_t refCount = 0;\n\n\tvirtual ~RC"
},
{
"path": "Physics3D/datastructures/uniqueArrayPtr.h",
"chars": 1942,
"preview": "#include <cstddef>\n#include <utility>\n#include <assert.h>\n\nnamespace P3D {\ntemplate<typename T>\nstruct DefaultArrayDelet"
},
{
"path": "Physics3D/datastructures/unmanagedArray.h",
"chars": 1285,
"preview": "\n#include <cstddef>\n#include <utility>\n#include <assert.h>\n\n/*\n\tWarning: This is an unmanaged object, does not automatic"
},
{
"path": "Physics3D/datastructures/unorderedVector.h",
"chars": 390,
"preview": "#pragma once\n\n#include <vector>\n#include <assert.h>\n\nnamespace P3D {\ntemplate<typename T>\nclass UnorderedVector : public"
},
{
"path": "Physics3D/externalforces/directionalGravity.cpp",
"chars": 708,
"preview": "#include \"directionalGravity.h\"\n\n#include \"../math/position.h\"\n#include \"../part.h\"\n#include \"../physical.h\"\n#include \"."
},
{
"path": "Physics3D/externalforces/directionalGravity.h",
"chars": 567,
"preview": "#pragma once\n\n#include \"../math/linalg/vec.h\"\n#include \"externalForce.h\"\n\nnamespace P3D {\nclass WorldPrototype;\nclass Pa"
},
{
"path": "Physics3D/externalforces/externalForce.cpp",
"chars": 732,
"preview": "#include \"externalForce.h\"\n\n#include \"../world.h\"\n#include \"../part.h\"\n#include \"../physical.h\"\n\nnamespace P3D {\ndouble "
},
{
"path": "Physics3D/externalforces/externalForce.h",
"chars": 642,
"preview": "#pragma once\n\nnamespace P3D {\nclass WorldPrototype;\nclass Part;\nclass MotorizedPhysical;\n\nclass ExternalForce {\npublic:\n"
},
{
"path": "Physics3D/externalforces/magnetForce.cpp",
"chars": 1509,
"preview": "#include \"magnetForce.h\"\n\n#include \"../world.h\"\n\nnamespace P3D {\n\nMagnetForce::MagnetForce(double pickerStrength, double"
},
{
"path": "Physics3D/externalforces/magnetForce.h",
"chars": 600,
"preview": "#pragma once\n\n#include \"externalForce.h\"\n#include \"../part.h\"\n#include \"../math/linalg/vec.h\"\n#include \"../math/position"
},
{
"path": "Physics3D/geometry/builtinShapeClasses.cpp",
"chars": 16917,
"preview": "#include \"builtinShapeClasses.h\"\n\n#include \"shapeCreation.h\"\n#include \"shapeLibrary.h\"\n#include \"../math/constants.h\"\n\n"
},
{
"path": "Physics3D/geometry/builtinShapeClasses.h",
"chars": 5070,
"preview": "#pragma once\n\n#include \"polyhedron.h\"\n#include \"shapeClass.h\"\n\nnamespace P3D {\n#define CUBE_CLASS_ID 0\n#define SPHERE_CL"
},
{
"path": "Physics3D/geometry/computationBuffer.cpp",
"chars": 1793,
"preview": "#include \"computationBuffer.h\"\n\n#include \"../misc/debug.h\"\n#include \"genericIntersection.h\"\n\nnamespace P3D {\nComputation"
},
{
"path": "Physics3D/geometry/computationBuffer.h",
"chars": 912,
"preview": "#pragma once\n\n#include \"../math/linalg/vec.h\"\n#include \"convexShapeBuilder.h\"\n\nnamespace P3D {\nstruct MinkowskiPointIndi"
},
{
"path": "Physics3D/geometry/convexShapeBuilder.cpp",
"chars": 8660,
"preview": "#include \"convexShapeBuilder.h\"\n\n#include <algorithm>\n#include <vector>\n#include <utility>\n\n#include \"../misc/validityHe"
},
{
"path": "Physics3D/geometry/convexShapeBuilder.h",
"chars": 1220,
"preview": "#pragma once\n\n#include \"indexedShape.h\"\n#include \"shapeBuilder.h\"\n#include \"../datastructures/sharedArray.h\"\n\nnamespace "
},
{
"path": "Physics3D/geometry/genericCollidable.h",
"chars": 166,
"preview": "#pragma once\n\n#include \"../math/linalg/vec.h\"\n\nnamespace P3D {\nstruct GenericCollidable {\n\tvirtual Vec3f furthestInDirec"
},
{
"path": "Physics3D/geometry/genericIntersection.cpp",
"chars": 9422,
"preview": "#include \"genericIntersection.h\"\n\n#include \"../math/linalg/vec.h\"\n#include \"convexShapeBuilder.h\"\n#include \"computationB"
},
{
"path": "Physics3D/geometry/genericIntersection.h",
"chars": 1686,
"preview": "#pragma once\n\n#include <optional>\n\n#include \"../math/linalg/vec.h\"\n#include \"../math/transform.h\"\n#include \"genericColli"
},
{
"path": "Physics3D/geometry/indexedShape.cpp",
"chars": 2162,
"preview": "#include \"indexedShape.h\"\n\n#include <stdexcept>\n#include \"../misc/validityHelper.h\"\n\nnamespace P3D {\nint& TriangleNeighb"
},
{
"path": "Physics3D/geometry/indexedShape.h",
"chars": 1019,
"preview": "#pragma once\n\n#include \"polyhedron.h\"\n#include \"../datastructures/sharedArray.h\"\n\nnamespace P3D {\nstruct TriangleNeighbo"
},
{
"path": "Physics3D/geometry/intersection.cpp",
"chars": 2720,
"preview": "#include \"intersection.h\"\n\n#include \"genericIntersection.h\"\n#include \"../misc/physicsProfiler.h\"\n#include \"../misc/profi"
},
{
"path": "Physics3D/geometry/intersection.h",
"chars": 744,
"preview": "#pragma once\n\n#include <optional>\n\n#include \"../math/linalg/vec.h\"\n#include \"../math/cframe.h\"\n#include \"genericCollidab"
},
{
"path": "Physics3D/geometry/polyhedron.cpp",
"chars": 6765,
"preview": "#include \"polyhedron.h\"\n\n#include \"../math/linalg/vec.h\"\n#include \"../math/utils.h\"\n#include \"../misc/debug.h\"\n#include "
},
{
"path": "Physics3D/geometry/polyhedron.h",
"chars": 1343,
"preview": "#pragma once\n\n#include \"../math/linalg/vec.h\"\n#include \"../math/linalg/mat.h\"\n#include \"../math/rotation.h\"\n#include \".."
},
{
"path": "Physics3D/geometry/scalableInertialMatrix.h",
"chars": 1342,
"preview": "#pragma once\n\n#include \"../math/linalg/vec.h\"\n#include \"../math/linalg/mat.h\"\n\nnamespace P3D {\nclass ScalableInertialMat"
},
{
"path": "Physics3D/geometry/shape.cpp",
"chars": 2559,
"preview": "#include \"shape.h\"\n\n#include \"polyhedron.h\"\n#include \"shapeClass.h\"\n\nnamespace P3D {\nShape::Shape() : baseShape(nullptr)"
},
{
"path": "Physics3D/geometry/shape.h",
"chars": 1795,
"preview": "#pragma once\n\n\n#include \"../math/boundingBox.h\"\n#include \"../math/linalg/vec.h\"\n#include \"../math/linalg/mat.h\"\n#include"
},
{
"path": "Physics3D/geometry/shapeBuilder.cpp",
"chars": 2244,
"preview": "#include \"shapeBuilder.h\"\n\nnamespace P3D {\nShapeBuilder::ShapeBuilder(Vec3f* vertBuf, Triangle* triangleBuf, int vertexC"
},
{
"path": "Physics3D/geometry/shapeBuilder.h",
"chars": 479,
"preview": "#pragma once\n\n#include \"shape.h\"\n#include \"indexedShape.h\"\n\nnamespace P3D {\nclass ShapeBuilder {\n\tVec3f* vertexBuf;\n\tTri"
},
{
"path": "Physics3D/geometry/shapeClass.cpp",
"chars": 708,
"preview": "#include \"shapeClass.h\"\n\nnamespace P3D {\nShapeClass::ShapeClass(double volume, Vec3 centerOfMass, ScalableInertialMatrix"
},
{
"path": "Physics3D/geometry/shapeClass.h",
"chars": 1915,
"preview": "#pragma once\n\n#include \"../math/linalg/vec.h\"\n#include \"../math/linalg/mat.h\"\n#include \"../math/rotation.h\"\n#include \".."
},
{
"path": "Physics3D/geometry/shapeCreation.cpp",
"chars": 1952,
"preview": "#include \"shapeCreation.h\"\n\n#include \"shapeClass.h\"\n#include \"polyhedron.h\"\n#include \"builtinShapeClasses.h\"\n\n#include \""
},
{
"path": "Physics3D/geometry/shapeCreation.h",
"chars": 384,
"preview": "#pragma once\n\n#include \"shape.h\"\n\nnamespace P3D {\nclass Polyhedron;\n\nShape boxShape(double width, double height, double "
},
{
"path": "Physics3D/geometry/shapeLibrary.cpp",
"chars": 14530,
"preview": "#include \"shapeLibrary.h\"\n\n#include <utility>\n#include <map>\n\n#include \"../datastructures/buffers.h\"\n\n#include \"../math/"
},
{
"path": "Physics3D/geometry/shapeLibrary.h",
"chars": 3044,
"preview": "#pragma once\n\n#include \"../geometry/polyhedron.h\"\n\nnamespace P3D::ShapeLibrary {\nextern const Polyhedron tetrahedron;\nex"
},
{
"path": "Physics3D/geometry/triangleMesh.cpp",
"chars": 21133,
"preview": "#include \"triangleMesh.h\"\n\n#include \"../misc/validityHelper.h\"\n#include \"../misc/cpuid.h\"\n\n#include <cstdio>\n#include <m"
},
{
"path": "Physics3D/geometry/triangleMesh.h",
"chars": 6820,
"preview": "#pragma once\n\n#define BLOCK_WIDTH 8\n\n#include \"../math/linalg/vec.h\"\n#include \"../math/cframe.h\"\n#include \"../math/bound"
},
{
"path": "Physics3D/geometry/triangleMeshAVX.cpp",
"chars": 9137,
"preview": "#include \"triangleMesh.h\"\n#include \"triangleMeshCommon.h\"\n\n#include <immintrin.h>\n\n// AVX2 implementation for TriangleMe"
},
{
"path": "Physics3D/geometry/triangleMeshCommon.h",
"chars": 1086,
"preview": "#pragma once\n\n#include \"triangleMesh.h\"\n#include <immintrin.h>\n\nnamespace P3D {\n#ifdef _MSC_VER\n#define GET_SSE_ELEM(reg"
},
{
"path": "Physics3D/geometry/triangleMeshSSE.cpp",
"chars": 14035,
"preview": "#include \"triangleMesh.h\"\n#include \"triangleMeshCommon.h\"\n\n#include <immintrin.h>\n\n// SSE2 implementation for TriangleMe"
},
{
"path": "Physics3D/geometry/triangleMeshSSE4.cpp",
"chars": 7355,
"preview": "#include \"triangleMesh.h\"\n#include \"triangleMeshCommon.h\"\n\n#include <immintrin.h>\n\n// SSE2 implementation for TriangleMe"
},
{
"path": "Physics3D/hardconstraints/constraintTemplates.h",
"chars": 2315,
"preview": "#pragma once\n\n#include \"hardConstraint.h\"\n\n/*\n\tRequires a SpeedController argument, this object must provide the followi"
},
{
"path": "Physics3D/hardconstraints/controller/constController.h",
"chars": 372,
"preview": "#pragma once\n\n#include \"../../math/taylorExpansion.h\"\n\nnamespace P3D {\nclass ConstController {\npublic:\n\tdouble value;\n\ti"
},
{
"path": "Physics3D/hardconstraints/controller/sineWaveController.cpp",
"chars": 1117,
"preview": "#include \"sineWaveController.h\"\n\n#include \"../../math/predefinedTaylorExpansions.h\"\n#include \"../../math/constants.h\"\n\nn"
},
{
"path": "Physics3D/hardconstraints/controller/sineWaveController.h",
"chars": 398,
"preview": "#pragma once\n\n#include \"../../math/taylorExpansion.h\"\n#include \"../../motion.h\"\n\nnamespace P3D {\nclass SineWaveControlle"
},
{
"path": "Physics3D/hardconstraints/fixedConstraint.cpp",
"chars": 371,
"preview": "#include \"fixedConstraint.h\"\n\nnamespace P3D {\nvoid FixedConstraint::update(double deltaT) {}\nvoid FixedConstraint::inver"
},
{
"path": "Physics3D/hardconstraints/fixedConstraint.h",
"chars": 520,
"preview": "#pragma once\n\n#include \"hardConstraint.h\"\nnamespace P3D {\n// Mostly used for debugging. You should instead use plain par"
},
{
"path": "Physics3D/hardconstraints/hardConstraint.cpp",
"chars": 197,
"preview": "#include \"hardConstraint.h\"\n\nnamespace P3D {\nCFrame HardConstraint::getRelativeCFrame() const {\n\treturn this->getRelativ"
},
{
"path": "Physics3D/hardconstraints/hardConstraint.h",
"chars": 492,
"preview": "#pragma once\n\n#include \"../math/cframe.h\"\n#include \"../motion.h\"\n#include \"../relativeMotion.h\"\n\n\n/*\n\tA HardConstraint i"
},
{
"path": "Physics3D/hardconstraints/hardPhysicalConnection.cpp",
"chars": 1062,
"preview": "#include \"hardPhysicalConnection.h\"\n\nnamespace P3D {\nHardPhysicalConnection::HardPhysicalConnection(std::unique_ptr<Hard"
},
{
"path": "Physics3D/hardconstraints/hardPhysicalConnection.h",
"chars": 571,
"preview": "#pragma once\n\n#include <memory>\n\n#include \"hardConstraint.h\"\n\n#include \"../math/cframe.h\"\n#include \"../relativeMotion.h\""
},
{
"path": "Physics3D/hardconstraints/motorConstraint.cpp",
"chars": 676,
"preview": "#include \"motorConstraint.h\"\n\n#include \"../math/linalg/trigonometry.h\"\n#include \"../math/constants.h\"\n\n#include \"../misc"
},
{
"path": "Physics3D/hardconstraints/motorConstraint.h",
"chars": 591,
"preview": "#pragma once\n\n#include \"hardConstraint.h\"\n#include \"constraintTemplates.h\"\n\nnamespace P3D {\nclass ConstantMotorTurner {\n"
},
{
"path": "Physics3D/hardconstraints/sinusoidalPistonConstraint.h",
"chars": 205,
"preview": "#include \"hardConstraint.h\"\n\n#include \"constraintTemplates.h\"\n#include \"controller/sineWaveController.h\"\n\nnamespace P3D "
},
{
"path": "Physics3D/inertia.cpp",
"chars": 6660,
"preview": "#include \"inertia.h\"\n\n#include \"math/linalg/trigonometry.h\"\n#include \"math/predefinedTaylorExpansions.h\"\n\nnamespace P3D "
},
{
"path": "Physics3D/inertia.h",
"chars": 4998,
"preview": "#pragma once\n\n#include \"math/linalg/mat.h\"\n#include \"math/cframe.h\"\n#include \"math/taylorExpansion.h\"\n#include \"motion.h"
},
{
"path": "Physics3D/layer.cpp",
"chars": 7884,
"preview": "#include \"layer.h\"\n#include \"world.h\"\n\n#include \"misc/validityHelper.h\"\n#include \"misc/debug.h\"\n#include \"misc/physicsPr"
},
{
"path": "Physics3D/layer.h",
"chars": 3388,
"preview": "#pragma once\n\n#include <vector>\n\n#include \"boundstree/boundsTree.h\"\n#include \"part.h\"\n#include \"colissionBuffer.h\"\n\nname"
},
{
"path": "Physics3D/math/boundingBox.h",
"chars": 2311,
"preview": "#pragma once\n\n#include \"linalg/vec.h\"\n\nnamespace P3D {\ntemplate<typename T>\nstruct BoundingBoxTemplate {\n\tVector<T, 3> m"
},
{
"path": "Physics3D/math/bounds.h",
"chars": 4004,
"preview": "#pragma once\n\n#include \"position.h\"\n#include \"boundingBox.h\"\n\n#include <fenv.h>\n\nnamespace P3D {\ntemplate<typename T>\nst"
},
{
"path": "Physics3D/math/cframe.h",
"chars": 5131,
"preview": "#pragma once\n\n#include \"linalg/vec.h\"\n#include \"rotation.h\"\n\nnamespace P3D {\ntemplate<typename T>\nstruct CFrameTemplate "
},
{
"path": "Physics3D/math/constants.h",
"chars": 1325,
"preview": "#pragma once\n\n#include <limits>\n\nnamespace P3D {\n#define EPSILON(T) epsilon<T>()\n#define PI pi<double>()\n#define E e<dou"
},
{
"path": "Physics3D/math/fix.h",
"chars": 8150,
"preview": "#pragma once\n\n#include <stdint.h>\n\nnamespace P3D {\ntemplate<int64_t N>\nstruct Fix {\n\tint64_t value;\n\n\tstatic constexpr i"
},
{
"path": "Physics3D/math/globalCFrame.h",
"chars": 5256,
"preview": "#pragma once\n\n#include \"position.h\"\n#include \"rotation.h\"\n#include \"cframe.h\"\n\nnamespace P3D {\nclass GlobalCFrame {\npubl"
},
{
"path": "Physics3D/math/globalTransform.h",
"chars": 2860,
"preview": "#pragma once\n\n#include \"position.h\"\n#include \"linalg/mat.h\"\n#include \"transform.h\"\n#include \"globalCFrame.h\"\n\nnamespace "
},
{
"path": "Physics3D/math/linalg/commonMatrices.h",
"chars": 1357,
"preview": "#pragma once\n\n#include \"mat.h\"\n#include \"quat.h\"\n#include \"../constants.h\"\n\nnamespace P3D {\n#define QROT_X_90(Type) Quat"
},
{
"path": "Physics3D/math/linalg/eigen.cpp",
"chars": 2196,
"preview": "#include \"eigen.h\"\n\n#include <cmath>\n\nnamespace P3D {\ntemplate<typename N>\nvoid update(EigenValues<N, 3>& e, bool* chang"
},
{
"path": "Physics3D/math/linalg/eigen.h",
"chars": 957,
"preview": "#pragma once\n\n#include \"mat.h\"\n#include <initializer_list>\n#include <stddef.h>\n\nnamespace P3D {\ntemplate<typename T, std"
},
{
"path": "Physics3D/math/linalg/largeMatrix.h",
"chars": 19733,
"preview": "#pragma once\n\n#include \"mat.h\"\n#include <utility>\n#include <assert.h>\n\nnamespace P3D {\ntemplate<typename T>\nclass Unmana"
},
{
"path": "Physics3D/math/linalg/largeMatrixAlgorithms.h",
"chars": 4158,
"preview": "#pragma once\n\n\n#include \"largeMatrix.h\"\n\n#include <utility>\n#include <cmath>\n#include <assert.h>\n#include <stddef.h>\n\nna"
},
{
"path": "Physics3D/math/linalg/mat.h",
"chars": 41438,
"preview": "#pragma once\n\n#include \"vec.h\"\n#include <initializer_list>\n#include <assert.h>\n#include <stddef.h>\n#include <cstddef>\n#i"
},
{
"path": "Physics3D/math/linalg/quat.h",
"chars": 4446,
"preview": "#pragma once\n\n#include <stddef.h>\n#include <cmath>\n#include \"vec.h\"\n\nnamespace P3D {\ntemplate<typename T>\nstruct Quatern"
},
{
"path": "Physics3D/math/linalg/trigonometry.cpp",
"chars": 2004,
"preview": "#include \"trigonometry.h\"\n#include \"mat.h\"\n\n#include <cmath>\n\nnamespace P3D {\ntemplate<typename T>\nMatrix<T, 4, 4> rotat"
},
{
"path": "Physics3D/math/linalg/trigonometry.h",
"chars": 11151,
"preview": "#pragma once\n\n#include \"vec.h\"\n#include \"mat.h\"\n#include \"quat.h\"\n\n#include <cmath>\n\nnamespace P3D {\n/*\n\tCreates a matri"
},
{
"path": "Physics3D/math/linalg/vec.h",
"chars": 18510,
"preview": "#pragma once\n\n#include <stddef.h>\n#include <cmath>\n#include <assert.h>\n\nnamespace P3D {\ntemplate<typename T, size_t Size"
},
{
"path": "Physics3D/math/mathUtil.h",
"chars": 1429,
"preview": "#pragma once\n\n#include <cstdlib>\n\nnamespace P3D {\n/*\n\tReturns a random number between fMin and fMax\n*/\ninline double fRa"
},
{
"path": "Physics3D/math/position.h",
"chars": 5486,
"preview": "#pragma once\n\n#include \"fix.h\"\n#include \"linalg/vec.h\"\n\nnamespace P3D {\ntypedef Vector<Fix<32>, 3> Vec3Fix;\n\ntemplate<ty"
},
{
"path": "Physics3D/math/predefinedTaylorExpansions.h",
"chars": 4571,
"preview": "#pragma once\n\n#include <cmath>\n#include <stddef.h>\n\n#include \"taylorExpansion.h\"\n#include \"linalg/trigonometry.h\"\n\nnames"
},
{
"path": "Physics3D/math/ray.h",
"chars": 3848,
"preview": "#pragma once\n\n#include \"linalg/vec.h\"\n#include \"position.h\"\n#include \"bounds.h\"\n\nnamespace P3D {\n\nstruct Ray {\n\tconstexp"
},
{
"path": "Physics3D/math/rotation.h",
"chars": 20585,
"preview": "#pragma once\n\n#include \"linalg/mat.h\"\n#include \"linalg/trigonometry.h\"\n#include \"linalg/quat.h\"\n#include \"constants.h\"\n\n"
},
{
"path": "Physics3D/math/taylorExpansion.h",
"chars": 16125,
"preview": "#pragma once\n\n#include <assert.h>\n#include <stddef.h>\n#include <initializer_list>\n\nnamespace P3D {\ntemplate<typename T, "
},
{
"path": "Physics3D/math/transform.h",
"chars": 3912,
"preview": "#pragma once\n\n#include \"linalg/vec.h\"\n#include \"linalg/mat.h\"\n#include \"cframe.h\"\n\nnamespace P3D {\ntemplate<typename T>\n"
},
{
"path": "Physics3D/math/utils.h",
"chars": 2531,
"preview": "#pragma once\n\n#include \"linalg/vec.h\"\n\nnamespace P3D {\n/*\n\tComputes the intersection of a line along <r> starting at r0\n"
},
{
"path": "Physics3D/misc/catchable_assert.h",
"chars": 413,
"preview": "#pragma once\n\n#include <exception>\n#include <string>\n\nnamespace P3D {\nclass assertion_error : public std::exception {\n\tc"
},
{
"path": "Physics3D/misc/cpuid.cpp",
"chars": 1420,
"preview": "#include \"cpuid.h\"\n\n#ifdef _WIN32\n#include <intrin.h>\n#endif\n\n#include <stdint.h>\n\nnamespace P3D {\nclass CPUID {\n\tuint32"
},
{
"path": "Physics3D/misc/cpuid.h",
"chars": 1369,
"preview": "#pragma once\n\nnamespace P3D {\nclass CPUIDCheck {\n\tunsigned int available;\n\n\tCPUIDCheck();\n\n\tstatic CPUIDCheck availableC"
},
{
"path": "Physics3D/misc/debug.cpp",
"chars": 3002,
"preview": "#include \"debug.h\"\n\n#include \"../geometry/shape.h\"\n#include \"../part.h\"\n\n#include \"serialization/serialization.h\"\n#inclu"
},
{
"path": "Physics3D/misc/debug.h",
"chars": 1461,
"preview": "#pragma once\n\n#include <cstdarg>\n\n#include \"../math/linalg/vec.h\"\n#include \"../math/position.h\"\n#include \"../math/cframe"
},
{
"path": "Physics3D/misc/physicsProfiler.cpp",
"chars": 1049,
"preview": "#include \"physicsProfiler.h\"\n\nnamespace P3D {\nconst char * physicsLabels[]{\n\t\"GJK Col\",\n\t\"GJK No Col\",\n\t\"EPA\",\n\t\"Collisi"
},
{
"path": "Physics3D/misc/physicsProfiler.h",
"chars": 971,
"preview": "#pragma once\n\n#include \"profiling.h\"\n\nnamespace P3D {\nenum class PhysicsProcess {\n\tGJK_COL,\n\tGJK_NO_COL,\n\tEPA,\n\tCOLISSIO"
},
{
"path": "Physics3D/misc/profiling.h",
"chars": 3941,
"preview": "#pragma once\n\n#include <chrono>\n#include <map>\n\n#include \"../datastructures/buffers.h\"\n#include \"../datastructures/paral"
},
{
"path": "Physics3D/misc/serialization/dynamicSerialize.h",
"chars": 4356,
"preview": "#pragma once\n\n#include \"serializeBasicTypes.h\"\n\nnamespace P3D {\ntypedef uint32_t ClassIDType;\ntemplate<typename BaseType"
},
{
"path": "Physics3D/misc/serialization/serialization.cpp",
"chars": 24962,
"preview": "#include \"serialization.h\"\n\n#include <map>\n#include <set>\n#include <limits.h>\n#include <string>\n#include <iostream>\n\n#in"
},
{
"path": "Physics3D/misc/serialization/serialization.h",
"chars": 8726,
"preview": "#pragma once\n\n#include <typeinfo>\n#include <typeindex>\n#include <iostream>\n#include <fstream>\n#include <vector>\n#include"
},
{
"path": "Physics3D/misc/serialization/serializeBasicTypes.cpp",
"chars": 1076,
"preview": "#include \"serializeBasicTypes.h\"\n\n#include <sstream>\n\nnamespace P3D {\nvoid serializeBasicTypes(const char* data, size_t "
},
{
"path": "Physics3D/misc/serialization/serializeBasicTypes.h",
"chars": 2233,
"preview": "#pragma once\n\n#include <iostream>\n#include <exception>\n#include <string>\n#include <type_traits>\n\nnamespace P3D {\nclass S"
},
{
"path": "Physics3D/misc/serialization/sharedObjectSerializer.h",
"chars": 4340,
"preview": "#pragma once\n\n#include <map>\n#include <vector>\n#include <assert.h>\n#include <limits>\n\n#include \"serializeBasicTypes.h\"\n\n"
},
{
"path": "Physics3D/misc/toString.h",
"chars": 7287,
"preview": "#pragma once\n\n#include <string>\n#include <sstream>\n#include <stddef.h>\n#include <iomanip>\n\n#include \"../math/linalg/vec."
},
{
"path": "Physics3D/misc/unreachable.h",
"chars": 468,
"preview": "#pragma once\n\nnamespace P3D {\n#ifdef NDEBUG\n#ifdef __GNUC__ // GCC 4.8+, Clang, Intel and other compilers compatible wit"
},
{
"path": "Physics3D/misc/validityHelper.cpp",
"chars": 6047,
"preview": "#include \"validityHelper.h\"\n\n#include <vector>\n#include <map>\n#include <set>\n\n#include \"../geometry/polyhedron.h\"\n#inclu"
},
{
"path": "Physics3D/misc/validityHelper.h",
"chars": 5571,
"preview": "#pragma once\n\n#include \"../math/linalg/vec.h\"\n#include \"../math/linalg/mat.h\"\n#include \"../math/linalg/largeMatrix.h\"\n#i"
},
{
"path": "Physics3D/motion.h",
"chars": 7601,
"preview": "#pragma once\n\n#include \"math/linalg/vec.h\"\n#include \"math/rotation.h\"\n\n#include \"math/taylorExpansion.h\"\n\nnamespace P3D "
},
{
"path": "Physics3D/part.cpp",
"chars": 12977,
"preview": "#include \"part.h\"\n\n#include \"physical.h\"\n\n#include \"geometry/intersection.h\"\n\n#include \"misc/validityHelper.h\"\n#include "
},
{
"path": "Physics3D/part.h",
"chars": 4469,
"preview": "#pragma once\n\n\n// this is a central class to everything else, but applications using the library don't need to include a"
},
{
"path": "Physics3D/physical.cpp",
"chars": 35321,
"preview": "#include \"physical.h\"\n\n#include \"inertia.h\"\n#include \"world.h\"\n#include \"math/linalg/mat.h\"\n#include \"math/linalg/trigon"
},
{
"path": "Physics3D/physical.h",
"chars": 18847,
"preview": "#pragma once\n\n#include \"math/linalg/vec.h\"\n#include \"math/linalg/mat.h\"\n#include \"math/cframe.h\"\n#include \"math/bounds.h"
},
{
"path": "Physics3D/relativeMotion.h",
"chars": 3081,
"preview": "#pragma once\n\n#include \"math/cframe.h\"\n#include \"motion.h\"\n\nnamespace P3D {\nstruct RelativeMotion {\n\tMotion relativeMoti"
},
{
"path": "Physics3D/rigidBody.cpp",
"chars": 5589,
"preview": "#include \"rigidBody.h\"\n\n#include \"inertia.h\"\n\n#include \"misc/validityHelper.h\"\n\n#include <assert.h>\n\nnamespace P3D {\nRig"
},
{
"path": "Physics3D/rigidBody.h",
"chars": 4995,
"preview": "#pragma once\n\n#include \"datastructures/unorderedVector.h\"\n#include \"datastructures/iteratorEnd.h\"\n#include \"part.h\"\n\nnam"
},
{
"path": "Physics3D/softlinks/alignmentLink.cpp",
"chars": 787,
"preview": "#include \"alignmentLink.h\"\n\nnamespace P3D {\nAlignmentLink::AlignmentLink(const AttachedPart& partA, const AttachedPart& "
},
{
"path": "Physics3D/softlinks/alignmentLink.h",
"chars": 542,
"preview": "#pragma once\n\n#include \"softLink.h\"\n\nnamespace P3D {\nclass AlignmentLink : public SoftLink {\npublic:\n\tRotation offset;\n\n"
},
{
"path": "Physics3D/softlinks/elasticLink.cpp",
"chars": 1010,
"preview": "#include \"elasticLink.h\"\n\nnamespace P3D {\nElasticLink::ElasticLink(const AttachedPart& partA, const AttachedPart& partB,"
},
{
"path": "Physics3D/softlinks/elasticLink.h",
"chars": 575,
"preview": "#pragma once\n\n\n#include \"softLink.h\"\n#include <optional>\n\nnamespace P3D {\nclass ElasticLink : public SoftLink {\n\npublic:"
},
{
"path": "Physics3D/softlinks/magneticLink.cpp",
"chars": 781,
"preview": "#include \"magneticLink.h\"\n\nnamespace P3D {\nMagneticLink::MagneticLink(const AttachedPart& partA, const AttachedPart& par"
},
{
"path": "Physics3D/softlinks/magneticLink.h",
"chars": 571,
"preview": "#pragma once\n\n#include \"softLink.h\"\n\nnamespace P3D {\nclass MagneticLink : public SoftLink {\npublic:\n\tdouble magneticStre"
},
{
"path": "Physics3D/softlinks/softLink.cpp",
"chars": 1661,
"preview": "#include \"softLink.h\"\n\nnamespace P3D {\n\nSoftLink::SoftLink(const AttachedPart& attachedPartA, const AttachedPart& attach"
},
{
"path": "Physics3D/softlinks/softLink.h",
"chars": 1112,
"preview": "#pragma once\n\n#include \"../math/linalg/vec.h\"\n#include \"../rigidBody.h\"\n#include \"../part.h\"\n\nnamespace P3D {\n\n\tclass So"
},
{
"path": "Physics3D/softlinks/springLink.cpp",
"chars": 841,
"preview": "#include \"springLink.h\"\n\nnamespace P3D {\nSpringLink::SpringLink(const AttachedPart& partA, const AttachedPart& partB, do"
},
{
"path": "Physics3D/softlinks/springLink.h",
"chars": 574,
"preview": "#pragma once\n\n#include \"softLink.h\"\n\nnamespace P3D {\nclass SpringLink : public SoftLink {\npublic:\n\tdouble restLength;\n\td"
},
{
"path": "Physics3D/threading/physicsThread.cpp",
"chars": 3059,
"preview": "#include \"physicsThread.h\"\n#include \"../world.h\"\n#include \"../worldPhysics.h\"\n#include \"../misc/physicsProfiler.h\"\n\n#inc"
},
{
"path": "Physics3D/threading/physicsThread.h",
"chars": 1724,
"preview": "#pragma once\n\n#include <thread>\n#include <atomic>\n\n#include \"threadPool.h\"\n#include \"upgradeableMutex.h\"\n\nnamespace P3D "
},
{
"path": "Physics3D/threading/sharedLockGuard.h",
"chars": 1164,
"preview": "#pragma once\n\n#include <shared_mutex>\n\nnamespace P3D {\nclass SharedLockGuard {\n\tstd::shared_mutex& mutex;\n\tbool isHard ="
},
{
"path": "Physics3D/threading/threadPool.h",
"chars": 2290,
"preview": "#pragma once\n\n#include <functional>\n#include <vector>\n#include <thread>\n#include <mutex>\n#include <condition_variable>\n\n"
},
{
"path": "Physics3D/threading/upgradeableMutex.cpp",
"chars": 1364,
"preview": "#include \"upgradeableMutex.h\"\n\n// disable \"Caller failing to hold lock 'this->writerLockout' before calling function 'st"
},
{
"path": "Physics3D/threading/upgradeableMutex.h",
"chars": 2250,
"preview": "#pragma once\n\n#include <mutex>\n#include <shared_mutex>\n\nnamespace P3D {\n/*\nThis mutex allows minimal reader interference"
},
{
"path": "Physics3D/world.cpp",
"chars": 9267,
"preview": "#include \"world.h\"\n\n#include <algorithm>\n#include \"misc/debug.h\"\n#include \"layer.h\"\n#include \"misc/validityHelper.h\"\n#in"
},
{
"path": "Physics3D/world.h",
"chars": 4489,
"preview": "#pragma once\n\n#include <vector>\n#include <mutex>\n#include <memory>\n\n#include \"part.h\"\n#include \"physical.h\"\n#include \"co"
},
{
"path": "Physics3D/worldIteration.h",
"chars": 1190,
"preview": "#pragma once\n\n#include \"world.h\"\n#include \"layer.h\"\n\nnamespace P3D {\n// expects a function of the form void(Part& part)\n"
},
{
"path": "Physics3D/worldPhysics.cpp",
"chars": 13948,
"preview": "#include \"worldPhysics.h\"\n\n#include \"world.h\"\n#include \"layer.h\"\n\n#include \"math/mathUtil.h\"\n#include \"math/linalg/vec.h"
},
{
"path": "Physics3D/worldPhysics.h",
"chars": 1187,
"preview": "#pragma once\n\n#include \"part.h\"\n#include \"math/linalg/vec.h\"\n#include \"math/position.h\"\n#include \"colissionBuffer.h\"\n#in"
},
{
"path": "Physics3D.sln",
"chars": 8596,
"preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.2940"
},
{
"path": "README.md",
"chars": 6460,
"preview": "# Physics3D\n\n\r\n\r\n#include \"resource.h\"\r\n\r\n#define APS"
},
{
"path": "application/application.vcxproj",
"chars": 15417,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.micros"
},
{
"path": "application/builtinWorlds.cpp",
"chars": 26903,
"preview": "#include \"core.h\"\n\n#include \"builtinWorlds.h\"\n\n#include \"worldBuilder.h\"\n\n#include \"extendedPart.h\"\n\n#include \"ecs/entit"
},
{
"path": "application/builtinWorlds.h",
"chars": 428,
"preview": "#pragma once\n\n#include \"worlds.h\"\n#include \"view/screen.h\"\n\nnamespace P3D::Application {\nvoid buildBenchmarkWorld(Player"
},
{
"path": "application/core.cpp",
"chars": 17,
"preview": "#include \"core.h\""
},
{
"path": "application/core.h",
"chars": 795,
"preview": "#pragma once\n\n#include <unordered_map>\n#include <functional>\n#include <algorithm>\n#include <utility>\n#include <string>\n#"
},
{
"path": "application/debugData.natvis",
"chars": 2847,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?> \n<AutoVisualizer xmlns=\"http://schemas.microsoft.com/vstudio/debugger/natvis/2010"
},
{
"path": "application/ecs/components.h",
"chars": 13907,
"preview": "#pragma once\n\n#include <string>\n#include <variant>\n#include <functional>\n\n#include <Physics3D/geometry/builtinShapeClass"
},
{
"path": "application/ecs/entityBuilder.h",
"chars": 3001,
"preview": "#pragma once\n\n#include <sstream>\n\n#include \"../engine/ecs/registry.h\"\n#include \"components.h\"\n\nnamespace P3D::Applicatio"
},
{
"path": "application/eventHandler.cpp",
"chars": 981,
"preview": "#include \"core.h\"\n\n#include \"eventHandler.h\"\n\n#include \"view/screen.h\"\n#include \"extendedPart.h\"\n\nnamespace P3D::Applica"
},
{
"path": "application/eventHandler.h",
"chars": 1613,
"preview": "#pragma once\n\nnamespace P3D::Application {\n\nclass Screen;\nstruct Camera;\nstruct ExtendedPart;\n\ntypedef void (*CameraMove"
},
{
"path": "application/extendedPart.cpp",
"chars": 4829,
"preview": "#include \"core.h\"\n\n#include \"application.h\"\n#include \"extendedPart.h\"\n#include \"ecs/components.h\"\n#include \"view/screen."
},
{
"path": "application/extendedPart.h",
"chars": 1266,
"preview": "#pragma once\n\n#include \"../graphics/ecs/components.h\"\n#include \"../graphics/extendedTriangleMesh.h\"\n#include <Physics3D/"
},
{
"path": "application/input/playerController.cpp",
"chars": 1659,
"preview": "#include \"core.h\"\n\n#include \"playerController.h\"\n\n\n#include <Physics3D/world.h>\n\n#include \"application.h\"\n#include \"view"
},
{
"path": "application/input/playerController.h",
"chars": 205,
"preview": "#pragma once\n\n#include <Physics3D/externalforces/externalForce.h>\n\nnamespace P3D::Application {\n\nclass PlayerController "
},
{
"path": "application/input/standardInputHandler.cpp",
"chars": 6529,
"preview": "#include \"core.h\"\n\n#include \"standardInputHandler.h\"\n\n#include <Physics3D/misc/toString.h>\n#include <Physics3D/world.h>\n"
},
{
"path": "application/input/standardInputHandler.h",
"chars": 665,
"preview": "#pragma once\n\n#include \"../engine/input/inputHandler.h\"\n#include \"../engine/event/keyEvent.h\"\n#include \"../engine/event/"
},
{
"path": "application/io/saveDialog.cpp",
"chars": 2701,
"preview": "#include \"core.h\"\n\n#include \"saveDialog.h\"\n\n#include <iostream>\n#include <stddef.h>\n#include <string.h>\n\nnamespace P3D::"
},
{
"path": "application/io/saveDialog.h",
"chars": 249,
"preview": "#pragma once\n\nnamespace P3D::Application {\n\nconstexpr size_t MAX_PATH_LENGTH = 1024;\n// returns true if user selected sa"
},
{
"path": "application/io/serialization.cpp",
"chars": 6430,
"preview": "#include \"core.h\"\n\n#include \"serialization.h\"\n\n#include \"../util/fileUtils.h\"\n\n#include \"extendedPart.h\"\n#include \"appli"
},
{
"path": "application/io/serialization.h",
"chars": 600,
"preview": "#pragma once\n\n#include <string>\n#include \"extendedPart.h\"\n\n#include \"../worlds.h\"\n#include \"../extendedPart.h\"\n\nnamespac"
},
{
"path": "application/layer/cameraLayer.cpp",
"chars": 2733,
"preview": "#include \"core.h\"\n\n#include \"cameraLayer.h\"\n\n#include \"../view/screen.h\"\n#include \"../application/input/standardInputHan"
},
{
"path": "application/layer/cameraLayer.h",
"chars": 746,
"preview": "#pragma once\n\n#include \"../engine/layer/layer.h\"\n#include <chrono>\n\nnamespace P3D::Application {\n\nclass Screen;\n\nclass C"
},
{
"path": "application/layer/constraintLayer.cpp",
"chars": 10262,
"preview": "#include \"core.h\"\n#include \"constraintLayer.h\"\n\n#include \"worlds.h\"\n#include \"../view/screen.h\"\n#include \"../shader/shad"
},
{
"path": "application/layer/constraintLayer.h",
"chars": 618,
"preview": "#pragma once\n\n#include \"../engine/layer/layer.h\"\n\nnamespace P3D::Application {\n\nclass Screen;\n\nclass ConstraintLayer : p"
}
]
// ... and 348 more files (download for full content)
About this extraction
This page contains the full source code of the ThePhysicsGuys/Physics3D GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 548 files (2.1 MB), approximately 562.7k tokens, and a symbol index with 2072 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.