├── .editorconfig
├── .gitattributes
├── .gitignore
├── Jitter.sln
├── LICENSE.md
├── README.md
├── appveyor.yml
├── build.bat
├── component
├── Details.md
├── GettingStarted.md
├── License.md
└── component.yaml
├── media
└── Jitter Logo
│ ├── jitterstackbig.png
│ ├── jitterstacksmall.png
│ ├── jitterstringbig.png
│ ├── jitterstringsmall.png
│ ├── stack_1024x1024.png
│ ├── stack_128x128.png
│ ├── stack_256x256.png
│ ├── stack_4096x4096.png
│ └── stack_512x512.png
├── samples
└── JitterDemo
│ ├── JitterDemo.sln
│ └── JitterDemo
│ ├── Camera.cs
│ ├── Content
│ ├── Car.png
│ ├── ConvexDecomposition.obj
│ ├── JitterDemoContent.mgcb
│ ├── StaticMesh.x
│ ├── car.fbx
│ ├── checker.bmp
│ ├── cloth.png
│ ├── convexhull.x
│ ├── font1.spritefont
│ ├── font2.spritefont
│ ├── kooten.ttf
│ ├── logo1.png
│ ├── logo2.png
│ ├── torus.x
│ └── wheel.fbx
│ ├── Conversion.cs
│ ├── DebugDrawer.cs
│ ├── Display.cs
│ ├── Forces
│ ├── Buoyancy.cs
│ ├── ForceGenerator.cs
│ └── PseudoCloth.cs
│ ├── Game.ico
│ ├── GameThumbnail.png
│ ├── JitterDemo.cs
│ ├── JitterDemo.csproj
│ ├── PhysicsObjects
│ ├── ClothObject.cs
│ ├── ConvexHullObject.cs
│ ├── TerrainObject.cs
│ └── Vehicle
│ │ ├── CarObject.cs
│ │ ├── DefaultCar.cs
│ │ └── Wheel.cs
│ ├── Primitives3D
│ ├── BoxPrimitive.cs
│ ├── CapsulePrimitive.cs
│ ├── ConePrimitive.cs
│ ├── ConvexHullPrimitive.cs
│ ├── CylinderPrimitive.cs
│ ├── DrawManager.cs
│ ├── GeometricPrimitive.cs
│ ├── SpherePrimitive.cs
│ ├── TerrainPrimitive.cs
│ └── VertexPositionNormal.cs
│ ├── Program.cs
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── QuadDrawer.cs
│ ├── Scenes
│ ├── BroadphaseStress.cs
│ ├── Cardhouse.cs
│ ├── Cloth.cs
│ ├── ConvexDecomposition.cs
│ ├── CylinderWall.cs
│ ├── Domino.cs
│ ├── EmptyScene.cs
│ ├── Jenga.cs
│ ├── NewtonCradle.cs
│ ├── PrismaticJointTest.cs
│ ├── Pyramid.cs
│ ├── Ragdoll.cs
│ ├── Restitution.cs
│ ├── Rope.cs
│ ├── Scene.cs
│ ├── SoftBodyJenga.cs
│ ├── Terrain.cs
│ ├── Tower.cs
│ ├── TriangleMesh.cs
│ └── Wall.cs
│ └── app.config
├── source
├── Jitter.sln
└── Jitter
│ ├── ArrayResourcePool.cs
│ ├── Collision
│ ├── CollisionIsland.cs
│ ├── CollisionSystem.cs
│ ├── CollisionSystemBrute.cs
│ ├── CollisionSystemPersistentSAP.cs
│ ├── CollisionSystemSAP.cs
│ ├── DynamicTree.cs
│ ├── DynamicTreeNode.cs
│ ├── GJKCollide.cs
│ ├── IBroadphaseEntity.cs
│ ├── IslandManager.cs
│ ├── Octree.cs
│ ├── Shapes
│ │ ├── BoxShape.cs
│ │ ├── CapsuleShape.cs
│ │ ├── CompoundShape.cs
│ │ ├── ConeShape.cs
│ │ ├── ConvexHullShape.cs
│ │ ├── CylinderShape.cs
│ │ ├── MinkowskiSumShape.cs
│ │ ├── Multishape.cs
│ │ ├── Shape.cs
│ │ ├── SphereShape.cs
│ │ ├── TerrainShape.cs
│ │ └── TriangleMeshShape.cs
│ ├── TriangleVertexIndices.cs
│ └── XenoCollide.cs
│ ├── DataStructures
│ └── ReadOnlyHashset.cs
│ ├── Dynamics
│ ├── Arbiter.cs
│ ├── ArbiterKey.cs
│ ├── ArbiterKeyComparer.cs
│ ├── ArbiterMap.cs
│ ├── Constraint.cs
│ ├── Constraints
│ │ ├── FixedAngle.cs
│ │ ├── PointOnLine.cs
│ │ ├── PointOnPoint.cs
│ │ ├── PointPointDistance.cs
│ │ └── SingleBody
│ │ │ ├── FixedAngle.cs
│ │ │ ├── PointOnLine.cs
│ │ │ └── PointOnPoint.cs
│ ├── Contact.cs
│ ├── ContactSettings.cs
│ ├── IConstraint.cs
│ ├── Joints
│ │ ├── HingeJoint.cs
│ │ ├── Joint.cs
│ │ ├── LimitedHingeJoint.cs
│ │ └── PrismaticJoint.cs
│ ├── Material.cs
│ ├── RigidBody.cs
│ └── SoftBody.cs
│ ├── IDebugDraw.cs
│ ├── Jitter.csproj
│ ├── LinearMath
│ ├── JBBox.cs
│ ├── JConvexHull.cs
│ ├── JMath.cs
│ ├── JMatrix.cs
│ ├── JQuaternion.cs
│ └── JVector.cs
│ ├── ResourcePool.cs
│ ├── ThreadManager.cs
│ └── World.cs
└── tools
└── hacdtest
├── ConvexDecomposition.obj
├── ReadMe.txt
├── TestHACD.exe
├── bunny.obj
└── hornbug.obj
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | build/
21 | bld/
22 | [Bb]in/
23 | [Oo]bj/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | artifacts/
46 |
47 | *_i.c
48 | *_p.c
49 | *_i.h
50 | *.ilk
51 | *.meta
52 | *.obj
53 | *.pch
54 | *.pdb
55 | *.pgc
56 | *.pgd
57 | *.rsp
58 | *.sbr
59 | *.tlb
60 | *.tli
61 | *.tlh
62 | *.tmp
63 | *.tmp_proj
64 | *.log
65 | *.vspscc
66 | *.vssscc
67 | .builds
68 | *.pidb
69 | *.svclog
70 | *.scc
71 |
72 | # Chutzpah Test files
73 | _Chutzpah*
74 |
75 | # Visual C++ cache files
76 | ipch/
77 | *.aps
78 | *.ncb
79 | *.opendb
80 | *.opensdf
81 | *.sdf
82 | *.cachefile
83 |
84 | # Visual Studio profiler
85 | *.psess
86 | *.vsp
87 | *.vspx
88 | *.sap
89 |
90 | # TFS 2012 Local Workspace
91 | $tf/
92 |
93 | # Guidance Automation Toolkit
94 | *.gpState
95 |
96 | # ReSharper is a .NET coding add-in
97 | _ReSharper*/
98 | *.[Rr]e[Ss]harper
99 | *.DotSettings.user
100 |
101 | # JustCode is a .NET coding add-in
102 | .JustCode
103 |
104 | # TeamCity is a build add-in
105 | _TeamCity*
106 |
107 | # DotCover is a Code Coverage Tool
108 | *.dotCover
109 |
110 | # NCrunch
111 | _NCrunch_*
112 | .*crunch*.local.xml
113 | nCrunchTemp_*
114 |
115 | # MightyMoose
116 | *.mm.*
117 | AutoTest.Net/
118 |
119 | # Web workbench (sass)
120 | .sass-cache/
121 |
122 | # Installshield output folder
123 | [Ee]xpress/
124 |
125 | # DocProject is a documentation generator add-in
126 | DocProject/buildhelp/
127 | DocProject/Help/*.HxT
128 | DocProject/Help/*.HxC
129 | DocProject/Help/*.hhc
130 | DocProject/Help/*.hhk
131 | DocProject/Help/*.hhp
132 | DocProject/Help/Html2
133 | DocProject/Help/html
134 |
135 | # Click-Once directory
136 | publish/
137 |
138 | # Publish Web Output
139 | *.[Pp]ublish.xml
140 | *.azurePubxml
141 | # TODO: Comment the next line if you want to checkin your web deploy settings
142 | # but database connection strings (with potential passwords) will be unencrypted
143 | *.pubxml
144 | *.publishproj
145 |
146 | # NuGet Packages
147 | *.nupkg
148 | # The packages folder can be ignored because of Package Restore
149 | **/packages/*
150 | # except build/, which is used as an MSBuild target.
151 | !**/packages/build/
152 | # Uncomment if necessary however generally it will be regenerated when needed
153 | #!**/packages/repositories.config
154 |
155 | # Windows Azure Build Output
156 | csx/
157 | *.build.csdef
158 |
159 | # Windows Azure Emulator
160 | ecf/
161 | rcf/
162 |
163 | # Windows Store app package directory
164 | AppPackages/
165 |
166 | # Visual Studio cache files
167 | # files ending in .cache can be ignored
168 | *.[Cc]ache
169 | # but keep track of directories ending in .cache
170 | !*.[Cc]ache/
171 |
172 | # Others
173 | ClientBin/
174 | [Ss]tyle[Cc]op.*
175 | ~$*
176 | *~
177 | *.dbmdl
178 | *.dbproj.schemaview
179 | *.pfx
180 | *.publishsettings
181 | node_modules/
182 | orleans.codegen.cs
183 |
184 | # RIA/Silverlight projects
185 | Generated_Code/
186 |
187 | # Backup & report files from converting an old project file
188 | # to a newer Visual Studio version. Backup files are not needed,
189 | # because we have git ;-)
190 | _UpgradeReport_Files/
191 | Backup*/
192 | UpgradeLog*.XML
193 | UpgradeLog*.htm
194 |
195 | # SQL Server files
196 | *.mdf
197 | *.ldf
198 |
199 | # Business Intelligence projects
200 | *.rdl.data
201 | *.bim.layout
202 | *.bim_*.settings
203 |
204 | # Microsoft Fakes
205 | FakesAssemblies/
206 |
207 | # GhostDoc plugin setting file
208 | *.GhostDoc.xml
209 |
210 | # Node.js Tools for Visual Studio
211 | .ntvs_analysis.dat
212 |
213 | # Visual Studio 6 build log
214 | *.plg
215 |
216 | # Visual Studio 6 workspace options file
217 | *.opt
218 |
219 | # Visual Studio LightSwitch build output
220 | **/*.HTMLClient/GeneratedArtifacts
221 | **/*.DesktopClient/GeneratedArtifacts
222 | **/*.DesktopClient/ModelManifest.xml
223 | **/*.Server/GeneratedArtifacts
224 | **/*.Server/ModelManifest.xml
225 | _Pvt_Extensions
226 |
227 | # Paket dependency manager
228 | .paket/paket.exe
229 |
230 | # FAKE - F# Make
231 | .fake/
232 |
233 | output/
234 |
--------------------------------------------------------------------------------
/Jitter.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29001.49
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jitter", "source\Jitter\Jitter.csproj", "{AA03EF1A-94F7-4D30-AB14-2092863FF923}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Debug|ARM = Debug|ARM
12 | Debug|x86 = Debug|x86
13 | Release|Any CPU = Release|Any CPU
14 | Release|ARM = Release|ARM
15 | Release|x86 = Release|x86
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {AA03EF1A-94F7-4D30-AB14-2092863FF923}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {AA03EF1A-94F7-4D30-AB14-2092863FF923}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {AA03EF1A-94F7-4D30-AB14-2092863FF923}.Debug|ARM.ActiveCfg = Debug|Any CPU
21 | {AA03EF1A-94F7-4D30-AB14-2092863FF923}.Debug|ARM.Build.0 = Debug|Any CPU
22 | {AA03EF1A-94F7-4D30-AB14-2092863FF923}.Debug|x86.ActiveCfg = Debug|Any CPU
23 | {AA03EF1A-94F7-4D30-AB14-2092863FF923}.Debug|x86.Build.0 = Debug|Any CPU
24 | {AA03EF1A-94F7-4D30-AB14-2092863FF923}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {AA03EF1A-94F7-4D30-AB14-2092863FF923}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {AA03EF1A-94F7-4D30-AB14-2092863FF923}.Release|ARM.ActiveCfg = Release|Any CPU
27 | {AA03EF1A-94F7-4D30-AB14-2092863FF923}.Release|ARM.Build.0 = Release|Any CPU
28 | {AA03EF1A-94F7-4D30-AB14-2092863FF923}.Release|x86.ActiveCfg = Release|Any CPU
29 | {AA03EF1A-94F7-4D30-AB14-2092863FF923}.Release|x86.Build.0 = Release|Any CPU
30 | EndGlobalSection
31 | GlobalSection(SolutionProperties) = preSolution
32 | HideSolutionNode = FALSE
33 | EndGlobalSection
34 | GlobalSection(ExtensibilityGlobals) = postSolution
35 | SolutionGuid = {9C7BED84-7617-412B-A88A-9E106EBAD5FA}
36 | EndGlobalSection
37 | EndGlobal
38 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Thorben Linneweber, Matthew Leibowitz
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Jitter Physics
2 |
3 | [![JitterPhysics Build][appveyor-badge]][appveyor-link] [![JitterPhysics on NuGet][nuget-badge]][nuget-link]
4 |
5 | Jitter Physics is a fast and lightweight 3D physics engine written in C#.
6 |
7 | | Jitter Physics Cloth | Speculative Contacts Jitter Physics |
8 | | :-----------------------------------: | :--------------------------------------------------: |
9 | | [![Jitter Physics Cloth][img1]][vid1] | [![Speculative Contacts Jitter Physics][img2]][vid2] |
10 |
11 |
12 | **Platforms & Frameworks**
13 | - Every platform which supports .NET, Mono or Xamarin
14 | - Works with the Mono framework on Linux/Mac without any recompilation
15 | - Also supports the Xbox360 and Windows Phone _(up to v0.1.7)_
16 | - No dependencies. Every 3D engine/framework is supported: OpenTK, SlimDX,
17 | SharpDX, XNA, IrrlichtEngine, Urho3D
18 |
19 | **Overall Design**
20 | - Written in pure C# with a clean and object orientated API
21 | - Optimized for low to no garbage collections and maximum speed
22 | - Supported Shapes: TriangleMesh, Terrain, Compound, MinkowskiSum, Box, Sphere,
23 | Cylinder, Cone, Capsule, ConvexHull
24 | - Take advantage of multi-core CPUs by using the internal multithreading of
25 | the engine
26 |
27 | ## Jitter Physics (2D)
28 |
29 | The ["Jitter-2D" branch][jitter2d] is still in development an is not complete.
30 | At this time, it is probably better to make use of [Farseer Physics][farseer].
31 |
32 | ## Quick Start
33 |
34 | ### Initialize the Physics System
35 | Create a world class and initialize it with a `CollisionSystem`:
36 |
37 | CollisionSystem collision = new CollisionSystemSAP();
38 | World world = new World(collision);
39 |
40 | ### Add Objects to the World
41 | Create a shape of your choice and pass it to a body:
42 |
43 | Shape shape = new BoxShape(1.0f, 2.0f, 3.0f);
44 | RigidBody body = new RigidBody(shape);
45 |
46 | It's valid to use the same shape for different bodies.
47 | Set the position and orientation of the body by using it's properties.
48 | The next step is to add the `Body` to the world:
49 |
50 | world.AddBody(body);
51 |
52 | ### Run the Simulation
53 | Now you can call the `Step` method to integrate the world one timestep further.
54 | This should be done in you main game loop:
55 |
56 | while (gameRunning)
57 | {
58 | world.Step(1.0f / 100.0f, true);
59 |
60 | // do other stuff, like drawing
61 | }
62 |
63 | The first parameter is the timestep. This value should be as small as possible
64 | to get a stable simulation. The second parameter is for whether using internal
65 | multithreading or not. That's it the body is now simulated and affected by
66 | default gravity specified in `World.Gravity`. After each timestep the `Position`
67 | of the body should be different.
68 |
69 | ## Credits
70 |
71 | This library was originally written by Thorben Linneweber. Original source code can be found at https://code.google.com/archive/p/jitterphysics.
72 |
73 |
74 | [img1]: http://img.youtube.com/vi/cM23EJOFp3E/0.jpg
75 | [vid1]: http://www.youtube.com/watch?v=
76 | [img2]: http://img.youtube.com/vi/bKP2GZLlPWA/0.jpg
77 | [vid2]: http://www.youtube.com/watch?v=bKP2GZLlPWA
78 | [jitter2d]: https://github.com/mattleibow/jitterphysics/tree/Jitter-2D
79 | [farseer]: https://farseerphysics.codeplex.com/
80 |
81 | [appveyor-badge]: https://img.shields.io/appveyor/ci/mattleibow/JitterPhysics/master.svg?style=flat-square
82 | [appveyor-link]: https://ci.appveyor.com/project/mattleibow/jitterphysics
83 | [nuget-badge]: https://img.shields.io/nuget/v/JitterPhysics.svg?style=flat-square
84 | [nuget-link]: https://www.nuget.org/packages/JitterPhysics/
85 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | # build variables
2 | os: Visual Studio 2015
3 | configuration: Release
4 | platform: Any CPU
5 | environment:
6 | LibraryVersion: 0.2.0
7 | xamarin:
8 | email:
9 | secure: +SUXZSPLHwp39+Yh09d2xxVGsEgHtlSD4NT1Og5h3sg=
10 | password:
11 | secure: Tvdf5rZl6IOCwZbvyj9B2w==
12 | android: true
13 | ios: true
14 |
15 | # versioning
16 | version: $(LibraryVersion).{build}
17 | assembly_info:
18 | patch: true
19 | file: '**\AssemblyInfo.*'
20 | assembly_version: $(LibraryVersion).0
21 | assembly_file_version: '{version}'
22 | assembly_informational_version: '{version}-{branch}'
23 |
24 | # packages
25 | install:
26 | - cinst 7zip -x86
27 | - cinst 7zip.commandline -x86
28 | - cinst xamarin-component -version 1.1.0.7
29 | - ps: |
30 | $tempDir="$pwd\temp"
31 | $installerUrl="http://www.monogame.net/releases/v3.4/MonoGameSetup.exe"
32 | $installerFile="$tempDir\MonoGameSetup.zip"
33 | $installerExtracted="$tempDir\MonoGameSetup"
34 | $programFiles = "${env:ProgramFiles(x86)}\"
35 |
36 | Write-Host "Downloading MonoGame to $installerFile..."
37 | If ((Test-Path $tempDir) -eq 0) {
38 | New-Item -ItemType Directory $tempDir
39 | }
40 | Invoke-WebRequest $installerUrl -OutFile $installerFile
41 |
42 | Write-Host "Extracting MonoGame to $installerExtracted..."
43 | 7z x -y $installerFile -o"$installerExtracted"
44 | Write-Host "Copying the MonoGame content pipeline to $programFiles..."
45 | Copy-Item "$installerExtracted\`$PROGRAMFILES\MSBuild\MonoGame" "$programFiles\MSBuild" -Recurse
46 |
47 | # build
48 | branches:
49 | only:
50 | - master
51 | before_build:
52 | - if not exist output mkdir output
53 | - if not exist output\net4 mkdir output\net4
54 | - if not exist output\Portable mkdir output\Portable
55 | - nuget restore source\Jitter.sln
56 | build:
57 | project: source\Jitter.sln
58 | verbosity: normal
59 | after_build:
60 | - ps: |
61 | $ErrorActionPreference = "Stop"
62 |
63 | $nugetVersion = "$env:APPVEYOR_BUILD_VERSION"
64 |
65 | Write-Host "Copying the output files..."
66 | copy source\Jitter\bin\net4\Release\Jitter.dll output\net4\
67 | copy source\Jitter\bin\net4\Release\Jitter.pdb output\net4\
68 | copy source\Jitter\bin\net4\Release\Jitter.xml output\net4\
69 | copy source\Jitter\bin\Portable\Release\Jitter.dll output\Portable\
70 | copy source\Jitter\bin\Portable\Release\Jitter.pdb output\Portable\
71 | copy source\Jitter\bin\Portable\Release\Jitter.xml output\Portable\
72 |
73 | Write-Host "Setting .nuspec version tag to $nugetVersion..."
74 | $content = (Get-Content nuget\Jitter.nuspec)
75 | $content = $content -replace '\$version\$', $nugetVersion
76 | $content | Out-File nuget\Jitter.nuspec
77 | nuget pack nuget\Jitter.nuspec -OutputDirectory output
78 |
79 | Write-Host "Setting component.yaml version tag to $nugetVersion..."
80 | $content = (Get-Content component\component.yaml)
81 | $content = $content -replace '\$version\$', $nugetVersion
82 | $content | Out-File component\component.yaml
83 | xamarin-component package ./component/
84 | mv component\*.xam output
85 |
86 | test_script:
87 | - ps: |
88 | $ErrorActionPreference = "Stop"
89 |
90 | Write-Host "Building the samples..."
91 |
92 | nuget restore samples\JitterDemo\JitterDemo.sln
93 | msbuild samples\JitterDemo\JitterDemo.sln /p:Configuration=$env:configuration /p:Platform="Any CPU"
94 | If ($LastExitCode -ne 0) {
95 | exit $LastExitCode
96 | }
97 |
98 | nuget restore samples\JitterOpenGLDemo\JitterOpenGLDemo.sln
99 | msbuild samples\JitterOpenGLDemo\JitterOpenGLDemo.sln /p:Configuration=$env:configuration /p:Platform="Any CPU"
100 | If ($LastExitCode -ne 0) {
101 | exit $LastExitCode
102 | }
103 |
104 | nuget restore samples\JitterPhoneDemo\SimpleJitterPhoneDemo.sln
105 | msbuild samples\JitterPhoneDemo\SimpleJitterPhoneDemo.sln /p:Configuration=$env:configuration /p:Platform="x86"
106 | If ($LastExitCode -ne 0) {
107 | exit $LastExitCode
108 | }
109 |
110 | nuget restore samples\JitterPortableSample\JitterSample.sln
111 | msbuild samples\JitterPortableSample\JitterSample.sln /p:Configuration=$env:configuration /p:Platform="Any CPU"
112 | If ($LastExitCode -ne 0) {
113 | exit $LastExitCode
114 | }
115 |
116 | # artifacts
117 | artifacts:
118 | - path: output\
119 | name: Jitter-$(APPVEYOR_BUILD_VERSION)
120 | type: zip
121 | - path: output\JitterPhysics*.nupkg
122 | - path: output\JitterPhysics*.xam
123 |
--------------------------------------------------------------------------------
/build.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | rem clean up any files / folders
4 | if not exist output mkdir output
5 | del /S /Q output
6 | for /D %%p in ("output\*") do rmdir "%%p" /s /q
7 |
8 |
9 | rem build 3D library
10 | msbuild source\Jitter.sln /p:Configuration=Release /t:Rebuild
11 |
12 | rem ready for packaging
13 | if not exist output\net4 mkdir output\net4
14 | if not exist output\Portable mkdir output\Portable
15 | copy source\Jitter\bin\net4\Release\Jitter.dll output\net4\
16 | copy source\Jitter\bin\net4\Release\Jitter.pdb output\net4\
17 | copy source\Jitter\bin\net4\Release\Jitter.xml output\net4\
18 | copy source\Jitter\bin\Portable\Release\Jitter.dll output\Portable\
19 | copy source\Jitter\bin\Portable\Release\Jitter.pdb output\Portable\
20 | copy source\Jitter\bin\Portable\Release\Jitter.xml output\Portable\
21 |
22 | rem package
23 | nuget pack nuget\Jitter.nuspec -OutputDirectory output
24 |
25 | rem package
26 | xamarin-component package ./component/
27 | mv component\*.xam output
28 |
--------------------------------------------------------------------------------
/component/Details.md:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | **Jitter Physics** is a fast and lightweight physics engine for all managed
7 | languages.
8 |
9 | **Platforms & Frameworks**
10 | - Every platform which supports .NET/Mono
11 | - Works with the Mono framework on Linux/Mac without any recompilation
12 | - No dependencies. Every 3D engine/framework is supported: OpenTK, SlimDX,
13 | SharpDX, XNA, MonoGame, IrrlichtEngine
14 |
15 | **Overall Design**
16 | - Written in pure C# with a clean and object orientated API
17 | - Optimized for low to no garbage collections and maximum speed
18 | - Supported Shapes: TriangleMesh, Terrain, Compound, MinkowskiSum, Box, Sphere,
19 | Cylinder, Cone, Capsule, ConvexHull
20 | - Take advantage of multi-core CPUs by using the internal multi-threading of
21 | the engine
22 |
23 | ## The Samples
24 | _The samples use the [MonoGame][mg] framework and the MonoGame content
25 | pipeline. To build the samples, and the content, the MonoGame content
26 | pipeline needs to be installed using the [MonoGame installer][mg-setup]._
27 |
28 | ## Quick Start
29 |
30 | ### Initialize the Physics System
31 | Create a `World` instance and initialize it with a `CollisionSystem`:
32 |
33 | CollisionSystem collision = new CollisionSystemSAP();
34 | World world = new World(collision);
35 |
36 | ### Add Objects to the World
37 | Create a shape of your choice, and pass it to a body:
38 |
39 | Shape shape = new BoxShape(1.0f, 2.0f, 3.0f);
40 | RigidBody body = new RigidBody(shape);
41 |
42 | It is valid to use the same shape for different bodies. The
43 | position and orientation of the body can be set using it's properties.
44 |
45 | The next step is to add the `Body` to the world:
46 |
47 | world.AddBody(body);
48 |
49 | ### Run the Simulation
50 | Now you can call the `Step` method to integrate the world one timestep further.
51 | This should be done in you main game loop:
52 |
53 | while (gameRunning)
54 | {
55 | world.Step(1.0f / 100.0f, true);
56 |
57 | // do other stuff, like drawing
58 | }
59 |
60 | The first parameter is the timestep. This value should be as small as possible
61 | to get a stable simulation. The second parameter is for whether using internal
62 | multi-threading or not. That's it the body is now simulated and affected by
63 | default gravity specified in `World.Gravity`. After each timestep the `Position`
64 | of the body should be different.
65 |
66 | [mg]: http://www.monogame.net/
67 | [mg-setup]: http://www.monogame.net/2015/04/29/monogame-3-4/
68 |
--------------------------------------------------------------------------------
/component/License.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Thorben Linneweber, Matthew Leibowitz
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/component/component.yaml:
--------------------------------------------------------------------------------
1 | %YAML 1.2
2 | ---
3 | name: Jitter Physics
4 | id: JitterPhysics
5 | publisher: Xamarin Inc
6 | publisher-url: https://xamarin.com
7 | summary: Jitter Physics is a fast and lightweight physics engine for all managed languages.
8 | version: $version$
9 | src-url: https://github.com/mattleibow/jitterphysics
10 |
11 | details: Details.md
12 | license: License.md
13 | getting-started: GettingStarted.md
14 |
15 | is_shell: true
16 | no_build: true
17 | skip_docs: true
18 | packages:
19 | android: JitterPhysics, Version=$version$
20 | ios: JitterPhysics, Version=$version$
21 | ios-unified: JitterPhysics, Version=$version$
22 | winphone-8.0: JitterPhysics, Version=$version$
23 | winphone-8.1: JitterPhysics, Version=$version$
24 | mac-unified: JitterPhysics, Version=$version$
25 | libraries:
26 | android: ../output/Portable/Jitter.dll
27 | ios: ../output/Portable/Jitter.dll
28 | ios-unified: ../output/Portable/Jitter.dll
29 | winphone-8.0: ../output/Portable/Jitter.dll
30 | winphone-8.1: ../output/Portable/Jitter.dll
31 | winrt: ../output/Portable/Jitter.dll
32 | mac-unified: ../output/Portable/Jitter.dll
33 | local-nuget-repo: ../output
34 |
35 | icons:
36 | - ../media/Jitter Logo/stack_128x128.png
37 | - ../media/Jitter Logo/stack_512x512.png
38 |
39 | samples:
40 | - name: Android Sample
41 | path: ../samples/JitterPortableSample/JitterAndroidSample.sln
42 | removeProjects:
43 | - Jitter.Portable
44 | installNuGets:
45 | - project: JitterAndroidSample
46 | packages: JitterPhysics
47 | - project: JitterSample
48 | packages: JitterPhysics
49 | - name: iOS Sample
50 | path: ../samples/JitterPortableSample/JitteriOSSample.sln
51 | removeProjects:
52 | - Jitter.Portable
53 | installNuGets:
54 | - project: JitteriOSSample
55 | packages: JitterPhysics
56 | - project: JitterSample
57 | packages: JitterPhysics
58 | - name: Windows Phone Sample
59 | path: ../samples/JitterPortableSample/JitterWPASample.sln
60 | removeProjects:
61 | - Jitter.Portable
62 | installNuGets:
63 | - project: JitterWPASample
64 | packages: JitterPhysics
65 | - project: JitterSample
66 | packages: JitterPhysics
67 |
--------------------------------------------------------------------------------
/media/Jitter Logo/jitterstackbig.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flurin137/jitterphysics/61b68656d72bbd41c46a959a0d66ccd48d55f0ae/media/Jitter Logo/jitterstackbig.png
--------------------------------------------------------------------------------
/media/Jitter Logo/jitterstacksmall.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flurin137/jitterphysics/61b68656d72bbd41c46a959a0d66ccd48d55f0ae/media/Jitter Logo/jitterstacksmall.png
--------------------------------------------------------------------------------
/media/Jitter Logo/jitterstringbig.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flurin137/jitterphysics/61b68656d72bbd41c46a959a0d66ccd48d55f0ae/media/Jitter Logo/jitterstringbig.png
--------------------------------------------------------------------------------
/media/Jitter Logo/jitterstringsmall.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flurin137/jitterphysics/61b68656d72bbd41c46a959a0d66ccd48d55f0ae/media/Jitter Logo/jitterstringsmall.png
--------------------------------------------------------------------------------
/media/Jitter Logo/stack_1024x1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flurin137/jitterphysics/61b68656d72bbd41c46a959a0d66ccd48d55f0ae/media/Jitter Logo/stack_1024x1024.png
--------------------------------------------------------------------------------
/media/Jitter Logo/stack_128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flurin137/jitterphysics/61b68656d72bbd41c46a959a0d66ccd48d55f0ae/media/Jitter Logo/stack_128x128.png
--------------------------------------------------------------------------------
/media/Jitter Logo/stack_256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flurin137/jitterphysics/61b68656d72bbd41c46a959a0d66ccd48d55f0ae/media/Jitter Logo/stack_256x256.png
--------------------------------------------------------------------------------
/media/Jitter Logo/stack_4096x4096.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flurin137/jitterphysics/61b68656d72bbd41c46a959a0d66ccd48d55f0ae/media/Jitter Logo/stack_4096x4096.png
--------------------------------------------------------------------------------
/media/Jitter Logo/stack_512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flurin137/jitterphysics/61b68656d72bbd41c46a959a0d66ccd48d55f0ae/media/Jitter Logo/stack_512x512.png
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.24720.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jitter.Portable", "..\..\source\Jitter\Jitter.Portable.csproj", "{AA03EF1A-94F7-4D30-AB14-2092863FF92A}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JitterDemo", "JitterDemo\JitterDemo.csproj", "{6D78166B-77BC-4BAF-97CC-A946D013145B}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {AA03EF1A-94F7-4D30-AB14-2092863FF92A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {AA03EF1A-94F7-4D30-AB14-2092863FF92A}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {AA03EF1A-94F7-4D30-AB14-2092863FF92A}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {AA03EF1A-94F7-4D30-AB14-2092863FF92A}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {6D78166B-77BC-4BAF-97CC-A946D013145B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {6D78166B-77BC-4BAF-97CC-A946D013145B}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {6D78166B-77BC-4BAF-97CC-A946D013145B}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {6D78166B-77BC-4BAF-97CC-A946D013145B}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | EndGlobal
29 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Content/Car.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flurin137/jitterphysics/61b68656d72bbd41c46a959a0d66ccd48d55f0ae/samples/JitterDemo/JitterDemo/Content/Car.png
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Content/car.fbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flurin137/jitterphysics/61b68656d72bbd41c46a959a0d66ccd48d55f0ae/samples/JitterDemo/JitterDemo/Content/car.fbx
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Content/checker.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flurin137/jitterphysics/61b68656d72bbd41c46a959a0d66ccd48d55f0ae/samples/JitterDemo/JitterDemo/Content/checker.bmp
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Content/cloth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flurin137/jitterphysics/61b68656d72bbd41c46a959a0d66ccd48d55f0ae/samples/JitterDemo/JitterDemo/Content/cloth.png
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Content/font1.spritefont:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
14 | kooten
15 |
16 |
20 | 14
21 |
22 |
26 | 0
27 |
28 |
32 | true
33 |
34 |
38 |
39 |
40 |
44 |
45 |
46 |
53 |
54 |
55 |
56 | ~
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Content/font2.spritefont:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
14 | kooten
15 |
16 |
20 | 10
21 |
22 |
26 | 0
27 |
28 |
32 | true
33 |
34 |
38 |
39 |
40 |
44 |
45 |
46 |
53 |
54 |
55 |
56 | ~
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Content/kooten.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flurin137/jitterphysics/61b68656d72bbd41c46a959a0d66ccd48d55f0ae/samples/JitterDemo/JitterDemo/Content/kooten.ttf
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Content/logo1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flurin137/jitterphysics/61b68656d72bbd41c46a959a0d66ccd48d55f0ae/samples/JitterDemo/JitterDemo/Content/logo1.png
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Content/logo2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flurin137/jitterphysics/61b68656d72bbd41c46a959a0d66ccd48d55f0ae/samples/JitterDemo/JitterDemo/Content/logo2.png
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Content/wheel.fbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flurin137/jitterphysics/61b68656d72bbd41c46a959a0d66ccd48d55f0ae/samples/JitterDemo/JitterDemo/Content/wheel.fbx
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Conversion.cs:
--------------------------------------------------------------------------------
1 | using Jitter.LinearMath;
2 | using Microsoft.Xna.Framework;
3 |
4 | namespace JitterDemo
5 | {
6 | public sealed class Conversion
7 | {
8 | public static JVector ToJitterVector(Vector3 vector)
9 | {
10 | return new JVector(vector.X, vector.Y, vector.Z);
11 | }
12 |
13 | public static Matrix ToXNAMatrix(JMatrix matrix)
14 | {
15 | return new Matrix(
16 | matrix.M11,
17 | matrix.M12,
18 | matrix.M13,
19 | 0.0f,
20 | matrix.M21,
21 | matrix.M22,
22 | matrix.M23,
23 | 0.0f,
24 | matrix.M31,
25 | matrix.M32,
26 | matrix.M33,
27 | 0.0f,
28 | 0.0f,
29 | 0.0f,
30 | 0.0f,
31 | 1.0f);
32 | }
33 |
34 | public static JMatrix ToJitterMatrix(Matrix matrix)
35 | {
36 | return new JMatrix
37 | {
38 | M11 = matrix.M11,
39 | M12 = matrix.M12,
40 | M13 = matrix.M13,
41 | M21 = matrix.M21,
42 | M22 = matrix.M22,
43 | M23 = matrix.M23,
44 | M31 = matrix.M31,
45 | M32 = matrix.M32,
46 | M33 = matrix.M33
47 | };
48 | }
49 |
50 | public static Vector3 ToXNAVector(JVector vector)
51 | {
52 | return new Vector3(vector.X, vector.Y, vector.Z);
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Display.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Xna.Framework;
2 | using Microsoft.Xna.Framework.Content;
3 | using Microsoft.Xna.Framework.Graphics;
4 | using System;
5 | using System.Collections.Generic;
6 |
7 | namespace JitterDemo
8 | {
9 | public class Display : DrawableGameComponent
10 | {
11 | private readonly ContentManager content;
12 | private SpriteBatch spriteBatch;
13 | private SpriteFont font1, font2;
14 | private Texture2D texture;
15 |
16 | private int frameRate = 0;
17 | private int frameCounter = 0;
18 | private TimeSpan elapsedTime = TimeSpan.Zero;
19 |
20 | private int bbWidth, bbHeight;
21 |
22 | public Display(Game game)
23 | : base(game)
24 | {
25 | content = new ContentManager(game.Services);
26 | DisplayText = new List();
27 | for (int i = 0; i < 25; i++)
28 | {
29 | DisplayText.Add(string.Empty);
30 | }
31 | }
32 |
33 | private void GraphicsDevice_DeviceReset(object sender, EventArgs e)
34 | {
35 | bbWidth = GraphicsDevice.PresentationParameters.BackBufferWidth;
36 | bbHeight = GraphicsDevice.PresentationParameters.BackBufferHeight;
37 | }
38 |
39 | protected override void LoadContent()
40 | {
41 | GraphicsDevice.DeviceReset += new EventHandler(GraphicsDevice_DeviceReset);
42 | GraphicsDevice_DeviceReset(null, null);
43 |
44 | spriteBatch = new SpriteBatch(GraphicsDevice);
45 | font1 = content.Load("Content/font1");
46 | font2 = content.Load("Content/font2");
47 |
48 | texture = content.Load("Content/logo2");
49 | }
50 |
51 | protected override void UnloadContent()
52 | {
53 | content.Unload();
54 | }
55 |
56 | public override void Update(GameTime gameTime)
57 | {
58 | elapsedTime += gameTime.ElapsedGameTime;
59 |
60 | if (elapsedTime > TimeSpan.FromSeconds(1))
61 | {
62 | elapsedTime -= TimeSpan.FromSeconds(1);
63 | frameRate = frameCounter;
64 | frameCounter = 0;
65 | }
66 | }
67 |
68 | public List DisplayText { set; get; }
69 |
70 | public override void Draw(GameTime gameTime)
71 | {
72 | frameCounter++;
73 |
74 | string fps = frameRate.ToString();
75 |
76 | spriteBatch.Begin();
77 |
78 | spriteBatch.Draw(texture, new Rectangle(bbWidth - 105, 5, 100, 91), Color.White);
79 | spriteBatch.DrawString(font1, fps, new Vector2(11, 6), Color.Black);
80 | spriteBatch.DrawString(font1, fps, new Vector2(12, 7), Color.Yellow);
81 |
82 | for (int i = 0; i < DisplayText.Count; i++)
83 | {
84 | if (!string.IsNullOrEmpty(DisplayText[i]))
85 | {
86 | // spriteBatch.DrawString(font2, DisplayText[i], new Vector2(11, 40 + (i * 20)), Color.White);
87 | }
88 | }
89 |
90 | spriteBatch.End();
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Forces/ForceGenerator.cs:
--------------------------------------------------------------------------------
1 | namespace Jitter.Forces
2 | {
3 | ///
4 | /// Base class for physic effect.
5 | ///
6 | public class ForceGenerator
7 | {
8 | ///
9 | ///
10 | ///
11 | protected World world;
12 |
13 | private readonly World.WorldStep preStep, postStep;
14 |
15 | ///
16 | ///
17 | ///
18 | ///
19 | public ForceGenerator(World world)
20 | {
21 | this.world = world;
22 |
23 | preStep = new World.WorldStep(PreStep);
24 | postStep = new World.WorldStep(PostStep);
25 |
26 | world.Events.PostStep += postStep;
27 | world.Events.PreStep += preStep;
28 | }
29 |
30 | ///
31 | ///
32 | ///
33 | ///
34 | public virtual void PreStep(float timeStep)
35 | {
36 | }
37 |
38 | ///
39 | ///
40 | ///
41 | ///
42 | public virtual void PostStep(float timeStep)
43 | {
44 | }
45 |
46 | ///
47 | ///
48 | ///
49 | public void RemoveEffect()
50 | {
51 | world.Events.PostStep -= postStep;
52 | world.Events.PreStep -= preStep;
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Forces/PseudoCloth.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using Jitter.Dynamics;
6 | using Jitter.Collision.Shapes;
7 | using Jitter.LinearMath;
8 | using Jitter.Dynamics.Constraints;
9 |
10 | namespace Jitter.Forces
11 | {
12 | public class PseudoCloth
13 | {
14 |
15 |
16 | public List constraints = new List();
17 |
18 | public class PseudoClothBody : RigidBody
19 | {
20 | public PseudoClothBody(float sphereRadius) : base(new SphereShape(sphereRadius)) { }
21 | }
22 |
23 | int sizeX, sizeY;
24 | float scale;
25 |
26 | World world;
27 |
28 | PseudoClothBody[] bodies;
29 |
30 | public PseudoCloth(World world, int sizeX, int sizeY, float scale)
31 | {
32 | bodies = new PseudoClothBody[sizeX * sizeY];
33 |
34 | for (int i = 0; i < sizeX; i++)
35 | {
36 | for (int e = 0; e < sizeX; e++)
37 | {
38 | bodies[i + e * sizeY] = new PseudoClothBody(0.1f);
39 | bodies[i + e * sizeY].Position = new JVector(i * scale, 0, e * scale) + JVector.Up * 10.0f;
40 | bodies[i + e * sizeY].StaticFriction =0.5f;
41 | bodies[i + e * sizeY].DynamicFriction = 0.5f;
42 | bodies[i + e * sizeY].Mass = 0.1f;
43 | world.AddBody(bodies[i + e * sizeY]);
44 | }
45 | }
46 |
47 | world.CollisionSystem.PassedBroadphase += new Collision.PassedBroadphaseHandler(CollisionSystem_PassedBroadphase);
48 | world.PostStep += new WorldStep(world_PostStep);
49 |
50 | this.world = world;
51 |
52 | for (int i = 0; i < sizeX; i++)
53 | {
54 | for (int e = 0; e < sizeY; e++)
55 | {
56 | if (i + 1 < sizeX)
57 | {
58 | AddDistance(e * sizeY + i, (i + 1) + e * sizeY);
59 | // (i,e) and (i+1,e)
60 | }
61 |
62 | if (e + 1 < sizeY)
63 | {
64 | AddDistance(e * sizeY + i, ((e + 1) * sizeY) + i);
65 | // (e,i) and (e+1,i)
66 |
67 | }
68 |
69 | if( (i + 1 < sizeX) && (e + 1 < sizeY))
70 | {
71 | AddDistance(e * sizeY + i, ((e + 1) * sizeY) +( i+1));
72 | }
73 |
74 |
75 | if ((i > 0) && (e + 1 < sizeY))
76 | {
77 | AddDistance(e * sizeY + i, ((e + 1) * sizeY) + (i - 1));
78 | }
79 |
80 |
81 | }
82 | }
83 |
84 | this.sizeX = sizeX;
85 | this.sizeY = sizeY;
86 | this.scale = scale;
87 |
88 | }
89 |
90 | void world_PostStep(float timeStep)
91 | {
92 | CheckConstraints();
93 | }
94 |
95 | public RigidBody GetCorner(int e,int i)
96 | {
97 | return bodies[e * sizeY + i];
98 | }
99 |
100 |
101 |
102 | private void AddDistance(int p1, int p2)
103 | {
104 | DistanceConstraint dc = new DistanceConstraint(bodies[p1], bodies[p2], bodies[p1].position, bodies[p2].position);
105 | dc.Softness = 2f;
106 | dc.BiasFactor = 0.1f;
107 | world.AddConstraint(dc);
108 | this.constraints.Add(dc);
109 | }
110 |
111 | public void CheckConstraints()
112 | {
113 | foreach (Constraint c in constraints)
114 | {
115 | if ((c as DistanceConstraint).AppliedImpulse.Length() > 1.8f)
116 | {
117 | world.constraints.Remove(c);
118 | }
119 | }
120 | }
121 |
122 |
123 |
124 |
125 |
126 |
127 | private bool CollisionSystem_PassedBroadphase(RigidBody body1, RigidBody body2)
128 | {
129 | // prevent PseudoClothBody,PseudoClothBody collisions
130 | return !(body1 is PseudoClothBody && body2 is PseudoClothBody);
131 | }
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Game.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flurin137/jitterphysics/61b68656d72bbd41c46a959a0d66ccd48d55f0ae/samples/JitterDemo/JitterDemo/Game.ico
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/GameThumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flurin137/jitterphysics/61b68656d72bbd41c46a959a0d66ccd48d55f0ae/samples/JitterDemo/JitterDemo/GameThumbnail.png
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/PhysicsObjects/TerrainObject.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using Microsoft.Xna.Framework;
6 | using Microsoft.Xna.Framework.Graphics;
7 | using Jitter.Collision.Shapes;
8 | using Jitter.Dynamics;
9 | using Jitter.LinearMath;
10 | using JitterDemo.Primitives3D;
11 |
12 | namespace JitterDemo
13 | {
14 | public class TerrainObject : DrawableGameComponent
15 | {
16 | TerrainPrimitive primitive;
17 | BasicEffect effect;
18 | RigidBody terrainBody;
19 |
20 | Matrix worldMatrix = Matrix.Identity;
21 |
22 | public Matrix World { get { return worldMatrix; }
23 | set
24 | {
25 | worldMatrix = value;
26 | terrainBody.Orientation = Conversion.ToJitterMatrix(worldMatrix);
27 | terrainBody.Position = Conversion.ToJitterVector(worldMatrix.Translation);
28 |
29 | }
30 | }
31 |
32 | public TerrainObject(Game game,BasicEffect effect)
33 | : base(game)
34 | {
35 | this.effect = effect;
36 | }
37 |
38 | public override void Initialize()
39 | {
40 | base.Initialize();
41 | primitive = new TerrainPrimitive(GraphicsDevice,
42 | (int a, int b) =>
43 | { return (float)(Math.Sin(a * 0.1f) * Math.Cos(b * 0.1f))*3; });
44 |
45 | JitterDemo demo = this.Game as JitterDemo;
46 |
47 | TerrainShape terrainShape = new TerrainShape(primitive.heights, 1.0f, 1.0f);
48 |
49 | terrainBody = new RigidBody(terrainShape);
50 | terrainBody.IsStatic = true;
51 | terrainBody.Tag = true;
52 |
53 | demo.World.AddBody(terrainBody);
54 |
55 | World = Matrix.CreateTranslation(-50, 0, -50);
56 | }
57 |
58 | public override void Draw(GameTime gameTime)
59 | {
60 | effect.DiffuseColor = Color.Red.ToVector3();
61 | primitive.AddWorldMatrix(worldMatrix);
62 | primitive.Draw(effect);
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/PhysicsObjects/Vehicle/CarObject.cs:
--------------------------------------------------------------------------------
1 | #region Using Statements
2 | using Microsoft.Xna.Framework;
3 | using Jitter.Collision.Shapes;
4 | using Jitter;
5 | using Jitter.LinearMath;
6 | using Microsoft.Xna.Framework.Input;
7 | using Microsoft.Xna.Framework.Graphics;
8 | #endregion
9 |
10 | namespace JitterDemo.Vehicle
11 | {
12 | public class CarObject : DrawableGameComponent
13 | {
14 | private Model chassisModel = null;
15 | private Model tireModel = null;
16 |
17 | public DefaultCar carBody = null;
18 |
19 | public CarObject(Game game)
20 | : base(game)
21 | {
22 | BuildCar();
23 | }
24 |
25 | private void BuildCar()
26 | {
27 | var demo = Game as JitterDemo;
28 | var world = demo.World;
29 |
30 | var lower = new CompoundShape.TransformedShape(
31 | new BoxShape(2.5f, 1f, 6.0f), JMatrix.Identity, JVector.Zero);
32 |
33 | var upper = new CompoundShape.TransformedShape(
34 | new BoxShape(2.0f, 0.5f, 3.0f), JMatrix.Identity, (JVector.Up * 0.75f) + (JVector.Backward * 1.0f));
35 |
36 | CompoundShape.TransformedShape[] subShapes = { lower, upper };
37 |
38 | Shape chassis = new CompoundShape(subShapes);
39 |
40 | //chassis = new BoxShape(2.5f, 1f, 6.0f);
41 |
42 | carBody = new DefaultCar(world, chassis)
43 | {
44 | // use the inertia of the lower box.
45 |
46 | // adjust some driving values
47 | SteerAngle = 30,
48 | DriveTorque = 155,
49 | AccelerationRate = 10,
50 | SteerRate = 2f
51 | };
52 | carBody.AdjustWheelValues();
53 |
54 | carBody.Tag = BodyTag.DontDrawMe;
55 | carBody.AllowDeactivation = false;
56 |
57 | // place the car two units above the ground.
58 | carBody.Position = new JVector(0, 5, 0);
59 |
60 | world.AddBody(carBody);
61 | }
62 |
63 | public override void Update(GameTime gameTime)
64 | {
65 | var keyState = Keyboard.GetState();
66 |
67 | float steer, accelerate;
68 | if (keyState.IsKeyDown(Keys.Up)) accelerate = 1.0f;
69 | else if (keyState.IsKeyDown(Keys.Down)) accelerate = -1.0f;
70 | else accelerate = 0.0f;
71 |
72 | if (keyState.IsKeyDown(Keys.Left)) steer = 1;
73 | else if (keyState.IsKeyDown(Keys.Right)) steer = -1;
74 | else steer = 0.0f;
75 |
76 | carBody.SetInput(accelerate, steer);
77 |
78 | base.Update(gameTime);
79 | }
80 |
81 | #region Draw Wheels
82 | private void DrawWheels()
83 | {
84 | var demo = Game as JitterDemo;
85 |
86 | for(int i = 0;i("car");
143 | tireModel = Game.Content.Load("wheel");
144 |
145 | base.LoadContent();
146 | }
147 |
148 | public override void Draw(GameTime gameTime)
149 | {
150 | DrawWheels();
151 | DrawChassis();
152 | base.Draw(gameTime);
153 | }
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Primitives3D/BoxPrimitive.cs:
--------------------------------------------------------------------------------
1 | #region File Description
2 | //-----------------------------------------------------------------------------
3 | // BoxPrimitive.cs
4 | //
5 | // Microsoft XNA Community Game Platform
6 | // Copyright (C) Microsoft Corporation. All rights reserved.
7 | //-----------------------------------------------------------------------------
8 | #endregion
9 |
10 | #region Using Statements
11 | using Microsoft.Xna.Framework;
12 | using Microsoft.Xna.Framework.Graphics;
13 | #endregion
14 |
15 | namespace JitterDemo.Primitives3D
16 | {
17 | ///
18 | /// Geometric primitive class for drawing cubes.
19 | ///
20 | public class BoxPrimitive : GeometricPrimitive
21 | {
22 | ///
23 | /// Constructs a new cube primitive, using default settings.
24 | ///
25 | public BoxPrimitive(GraphicsDevice graphicsDevice)
26 | : this(graphicsDevice, 1)
27 | {
28 | }
29 |
30 | ///
31 | /// Constructs a new cube primitive, with the specified size.
32 | ///
33 | public BoxPrimitive(GraphicsDevice graphicsDevice, float size)
34 | {
35 | // A cube has six faces, each one pointing in a different direction.
36 | Vector3[] normals =
37 | {
38 | new Vector3(0, 0, 1),
39 | new Vector3(0, 0, -1),
40 | new Vector3(1, 0, 0),
41 | new Vector3(-1, 0, 0),
42 | new Vector3(0, 1, 0),
43 | new Vector3(0, -1, 0),
44 | };
45 |
46 | // Create each face in turn.
47 | foreach (var normal in normals)
48 | {
49 | // Get two vectors perpendicular to the face normal and to each other.
50 | var side1 = new Vector3(normal.Y, normal.Z, normal.X);
51 | var side2 = Vector3.Cross(normal, side1);
52 |
53 | // Six indices (two triangles) per face.
54 | AddIndex(CurrentVertex + 0);
55 | AddIndex(CurrentVertex + 1);
56 | AddIndex(CurrentVertex + 2);
57 |
58 | AddIndex(CurrentVertex + 0);
59 | AddIndex(CurrentVertex + 2);
60 | AddIndex(CurrentVertex + 3);
61 |
62 | // Four vertices per face.
63 | AddVertex((normal - side1 - side2) * size / 2, normal);
64 | AddVertex((normal - side1 + side2) * size / 2, normal);
65 | AddVertex((normal + side1 + side2) * size / 2, normal);
66 | AddVertex((normal + side1 - side2) * size / 2, normal);
67 | }
68 |
69 | InitializePrimitive(graphicsDevice);
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Primitives3D/CapsulePrimitive.cs:
--------------------------------------------------------------------------------
1 | #region File Description
2 | //-----------------------------------------------------------------------------
3 | // CapsulePrimitive.cs
4 | //
5 | // Microsoft XNA Community Game Platform
6 | // Copyright (C) Microsoft Corporation. All rights reserved.
7 | //-----------------------------------------------------------------------------
8 | #endregion
9 |
10 | #region Using Statements
11 | using System;
12 | using Microsoft.Xna.Framework;
13 | using Microsoft.Xna.Framework.Graphics;
14 | #endregion
15 |
16 | namespace JitterDemo.Primitives3D
17 | {
18 | ///
19 | /// Geometric primitive class for drawing spheres.
20 | ///
21 | public class CapsulePrimitive : GeometricPrimitive
22 | {
23 | ///
24 | /// Constructs a new sphere primitive, using default settings.
25 | ///
26 | public CapsulePrimitive(GraphicsDevice graphicsDevice)
27 | : this(graphicsDevice, 1.0f,0.8f, 12)
28 | {
29 | }
30 |
31 | ///
32 | /// Constructs a new sphere primitive,
33 | /// with the specified size and tessellation level.
34 | ///
35 | public CapsulePrimitive(GraphicsDevice graphicsDevice,
36 | float diameter,float length, int tessellation)
37 | {
38 | if (tessellation % 2 != 0)
39 | throw new ArgumentOutOfRangeException("tessellation should be even");
40 |
41 | int verticalSegments = tessellation;
42 | int horizontalSegments = tessellation * 2;
43 |
44 | float radius = diameter / 2;
45 |
46 | // Start with a single vertex at the bottom of the sphere.
47 | AddVertex((Vector3.Down * radius) + (Vector3.Down * 0.5f * length), Vector3.Down);
48 |
49 | // Create rings of vertices at progressively higher latitudes.
50 | for (int i = 0; i < verticalSegments - 1; i++)
51 | {
52 | float latitude = ((i + 1) * MathHelper.Pi
53 | / verticalSegments) - MathHelper.PiOver2;
54 | float dy = (float)Math.Sin(latitude);
55 | float dxz = (float)Math.Cos(latitude);
56 |
57 | bool bla = false;
58 |
59 | if (i > (verticalSegments-2) / 2)
60 | {
61 | bla = true;
62 | }
63 |
64 | // Create a single ring of vertices at this latitude.
65 | for (int j = 0; j < horizontalSegments; j++)
66 | {
67 | float longitude = j * MathHelper.TwoPi / horizontalSegments;
68 |
69 | float dx = (float)Math.Cos(longitude) * dxz;
70 | float dz = (float)Math.Sin(longitude) * dxz;
71 |
72 | var normal = new Vector3(dx, dy, dz);
73 | var position = normal * radius;
74 |
75 | if (bla) position += Vector3.Up * 0.5f * length;
76 | else position += Vector3.Down * 0.5f * length;
77 |
78 | AddVertex(position, normal);
79 | }
80 | }
81 |
82 | // Finish with a single vertex at the top of the sphere.
83 | AddVertex((Vector3.Up * radius) + (Vector3.Up * 0.5f * length), Vector3.Up);
84 |
85 | // Create a fan connecting the bottom vertex to the bottom latitude ring.
86 | for (int i = 0; i < horizontalSegments; i++)
87 | {
88 | AddIndex(0);
89 | AddIndex(1 + ((i + 1) % horizontalSegments));
90 | AddIndex(1 + i);
91 | }
92 |
93 | // Fill the sphere body with triangles joining each pair of latitude rings.
94 | for (int i = 0; i < verticalSegments - 2; i++)
95 | {
96 | for (int j = 0; j < horizontalSegments; j++)
97 | {
98 | int nextI = i + 1;
99 | int nextJ = (j + 1) % horizontalSegments;
100 |
101 | AddIndex(1 + (i * horizontalSegments) + j);
102 | AddIndex(1 + (i * horizontalSegments) + nextJ);
103 | AddIndex(1 + (nextI * horizontalSegments) + j);
104 |
105 | AddIndex(1 + (i * horizontalSegments) + nextJ);
106 | AddIndex(1 + (nextI * horizontalSegments) + nextJ);
107 | AddIndex(1 + (nextI * horizontalSegments) + j);
108 | }
109 | }
110 |
111 | // Create a fan connecting the top vertex to the top latitude ring.
112 | for (int i = 0; i < horizontalSegments; i++)
113 | {
114 | AddIndex(CurrentVertex - 1);
115 | AddIndex(CurrentVertex - 2 - ((i + 1) % horizontalSegments));
116 | AddIndex(CurrentVertex - 2 - i);
117 | }
118 |
119 | InitializePrimitive(graphicsDevice);
120 | }
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Primitives3D/ConePrimitive.cs:
--------------------------------------------------------------------------------
1 | #region File Description
2 | //-----------------------------------------------------------------------------
3 | // ConePrimitive.cs
4 | //
5 | // Microsoft XNA Community Game Platform
6 | // Copyright (C) Microsoft Corporation. All rights reserved.
7 | //-----------------------------------------------------------------------------
8 | #endregion
9 |
10 | #region Using Statements
11 | using Microsoft.Xna.Framework;
12 | using Microsoft.Xna.Framework.Graphics;
13 | using System;
14 | #endregion
15 |
16 | namespace JitterDemo.Primitives3D
17 | {
18 | ///
19 | /// Geometric primitive class for drawing cubes.
20 | ///
21 | public class ConePrimitive : GeometricPrimitive
22 | {
23 | ///
24 | /// Constructs a new cube primitive, using default settings.
25 | ///
26 | public ConePrimitive(GraphicsDevice graphicsDevice)
27 | : this(graphicsDevice, 1.0f, 1.0f, 32)
28 | {
29 | }
30 |
31 | ///
32 | /// Constructs a new cube primitive, with the specified size.
33 | ///
34 | public ConePrimitive(GraphicsDevice graphicsDevice, float height, float radius, int tessellation)
35 | {
36 | // Create a ring of triangles around the outside of the cylinder.
37 | AddVertex(Vector3.Up * (2.0f / 3.0f) * height, Vector3.Up);
38 |
39 | for (int i = 0; i < tessellation; i++)
40 | {
41 | var normal = GetCircleVector(i, tessellation);
42 | AddVertex((normal * radius) + (1.0f / 3.0f * height * Vector3.Down), normal);
43 |
44 | AddIndex(0);
45 | AddIndex(i);
46 | AddIndex(i + 1);
47 | }
48 |
49 | AddIndex(0);
50 | AddIndex(tessellation);
51 | AddIndex(1);
52 |
53 | CreateCap(tessellation, 1.0f / 3.0f * height , radius, Vector3.Down);
54 |
55 | InitializePrimitive(graphicsDevice);
56 | }
57 |
58 | ///
59 | /// Helper method creates a triangle fan to close the ends of the cylinder.
60 | ///
61 | private void CreateCap(int tessellation, float height, float radius, Vector3 normal)
62 | {
63 | // Create cap indices.
64 | for (int i = 0; i < tessellation - 2; i++)
65 | {
66 | if (normal.Y > 0)
67 | {
68 | AddIndex(CurrentVertex);
69 | AddIndex(CurrentVertex + ((i + 1) % tessellation));
70 | AddIndex(CurrentVertex + ((i + 2) % tessellation));
71 | }
72 | else
73 | {
74 | AddIndex(CurrentVertex);
75 | AddIndex(CurrentVertex + ((i + 2) % tessellation));
76 | AddIndex(CurrentVertex + ((i + 1) % tessellation));
77 | }
78 | }
79 |
80 | // Create cap vertices.
81 | for (int i = 0; i < tessellation; i++)
82 | {
83 | var position = (GetCircleVector(i, tessellation) * radius)
84 | + (normal * height);
85 |
86 | AddVertex(position, normal);
87 | }
88 | }
89 |
90 | ///
91 | /// Helper method computes a point on a circle.
92 | ///
93 | private static Vector3 GetCircleVector(int i, int tessellation)
94 | {
95 | float angle = i * MathHelper.TwoPi / tessellation;
96 |
97 | float dx = (float)Math.Cos(angle);
98 | float dz = (float)Math.Sin(angle);
99 |
100 | return new Vector3(dx, 0, dz);
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Primitives3D/ConvexHullPrimitive.cs:
--------------------------------------------------------------------------------
1 | //using System;
2 | //using System.Collections.Generic;
3 | //using System.Linq;
4 | //using System.Text;
5 | //using Microsoft.Xna.Framework.Graphics;
6 | //using Microsoft.Xna.Framework;
7 | //using Jitter.LinearMath;
8 | //using JitterDemo;
9 |
10 | //namespace JitterDemo.Primitives3D
11 | //{
12 | // public class ConvexHullPrimitive : GeometricPrimitive
13 | // {
14 |
15 | // //public JConvexHull ConvexHull = new JConvexHull();
16 |
17 | // public ConvexHullPrimitive(GraphicsDevice device, List pointCloud)
18 | // {
19 | // JConvexHull.Build(pointCloud,JConvexHull.Approximation.Level5);
20 |
21 | // int counter = 0;
22 |
23 | // foreach (JConvexHull.Face face in ConvexHull.HullFaces)
24 | // {
25 | // this.AddVertex(Conversion.ToXNAVector(pointCloud[face.VertexC]), Conversion.ToXNAVector(face.Normal));
26 | // this.AddVertex(Conversion.ToXNAVector(pointCloud[face.VertexB]), Conversion.ToXNAVector(face.Normal));
27 | // this.AddVertex(Conversion.ToXNAVector(pointCloud[face.VertexA]), Conversion.ToXNAVector(face.Normal));
28 |
29 | // this.AddIndex(counter + 0);
30 | // this.AddIndex(counter + 1);
31 | // this.AddIndex(counter + 2);
32 |
33 | // counter+=3;
34 | // }
35 |
36 |
37 | // this.InitializePrimitive(device);
38 | // }
39 |
40 | // }
41 | //}
42 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Primitives3D/CylinderPrimitive.cs:
--------------------------------------------------------------------------------
1 | #region File Description
2 | //-----------------------------------------------------------------------------
3 | // CylinderPrimitive.cs
4 | //
5 | // Microsoft XNA Community Game Platform
6 | // Copyright (C) Microsoft Corporation. All rights reserved.
7 | //-----------------------------------------------------------------------------
8 | #endregion
9 |
10 | #region Using Statements
11 | using System;
12 | using Microsoft.Xna.Framework;
13 | using Microsoft.Xna.Framework.Graphics;
14 | #endregion
15 |
16 | namespace JitterDemo.Primitives3D
17 | {
18 | ///
19 | /// Geometric primitive class for drawing cylinders.
20 | ///
21 | public class CylinderPrimitive : GeometricPrimitive
22 | {
23 | ///
24 | /// Constructs a new cylinder primitive, using default settings.
25 | ///
26 | public CylinderPrimitive(GraphicsDevice graphicsDevice)
27 | : this(graphicsDevice, 1, 1, 32)
28 | {
29 | }
30 |
31 | ///
32 | /// Constructs a new cylinder primitive,
33 | /// with the specified size and tessellation level.
34 | ///
35 | public CylinderPrimitive(GraphicsDevice graphicsDevice,
36 | float height, float radius, int tessellation)
37 | {
38 | if (tessellation < 3)
39 | throw new ArgumentOutOfRangeException(nameof(tessellation));
40 |
41 | height /= 2;
42 |
43 | // Create a ring of triangles around the outside of the cylinder.
44 | for (int i = 0; i < tessellation; i++)
45 | {
46 | var normal = GetCircleVector(i, tessellation);
47 |
48 | AddVertex((normal * radius) + (Vector3.Up * height), normal);
49 | AddVertex((normal * radius) + (Vector3.Down * height), normal);
50 |
51 | AddIndex(i * 2);
52 | AddIndex((i * 2) + 1);
53 | AddIndex(((i * 2) + 2) % (tessellation * 2));
54 |
55 | AddIndex((i * 2) + 1);
56 | AddIndex(((i * 2) + 3) % (tessellation * 2));
57 | AddIndex(((i * 2) + 2) % (tessellation * 2));
58 | }
59 |
60 | // Create flat triangle fan caps to seal the top and bottom.
61 | CreateCap(tessellation, height, radius, Vector3.Up);
62 | CreateCap(tessellation, height, radius, Vector3.Down);
63 |
64 | InitializePrimitive(graphicsDevice);
65 | }
66 |
67 | ///
68 | /// Helper method creates a triangle fan to close the ends of the cylinder.
69 | ///
70 | private void CreateCap(int tessellation, float height, float radius, Vector3 normal)
71 | {
72 | // Create cap indices.
73 | for (int i = 0; i < tessellation - 2; i++)
74 | {
75 | if (normal.Y > 0)
76 | {
77 | AddIndex(CurrentVertex);
78 | AddIndex(CurrentVertex + ((i + 1) % tessellation));
79 | AddIndex(CurrentVertex + ((i + 2) % tessellation));
80 | }
81 | else
82 | {
83 | AddIndex(CurrentVertex);
84 | AddIndex(CurrentVertex + ((i + 2) % tessellation));
85 | AddIndex(CurrentVertex + ((i + 1) % tessellation));
86 | }
87 | }
88 |
89 | // Create cap vertices.
90 | for (int i = 0; i < tessellation; i++)
91 | {
92 | var position = (GetCircleVector(i, tessellation) * radius)
93 | + (normal * height);
94 |
95 | AddVertex(position, normal);
96 | }
97 | }
98 |
99 | ///
100 | /// Helper method computes a point on a circle.
101 | ///
102 | private static Vector3 GetCircleVector(int i, int tessellation)
103 | {
104 | float angle = i * MathHelper.TwoPi / tessellation;
105 |
106 | float dx = (float)Math.Cos(angle);
107 | float dz = (float)Math.Sin(angle);
108 |
109 | return new Vector3(dx, 0, dz);
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Primitives3D/DrawManager.cs:
--------------------------------------------------------------------------------
1 | namespace JitterDemo.Primitives3D
2 | {
3 | //public class DrawManager : DrawableGameComponent
4 | //{
5 |
6 | // public void RegisterDraw(GeometricPrimitive primitive, Matrix world)
7 | // {
8 | // }
9 |
10 | //}
11 | }
12 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Primitives3D/GeometricPrimitive.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Microsoft.Xna.Framework;
4 | using Microsoft.Xna.Framework.Graphics;
5 |
6 | namespace JitterDemo.Primitives3D
7 | {
8 | public abstract class GeometricPrimitive : IDisposable
9 | {
10 | private readonly List vertices = new List();
11 | private readonly List indices = new List();
12 |
13 | private VertexBuffer vertexBuffer;
14 | private IndexBuffer indexBuffer;
15 |
16 | protected void AddVertex(Vector3 position, Vector3 normal)
17 | {
18 | vertices.Add(new VertexPositionNormal(position, normal));
19 | }
20 |
21 | protected void AddIndex(int index)
22 | {
23 | if (index > ushort.MaxValue)
24 | throw new ArgumentOutOfRangeException(nameof(index));
25 |
26 | indices.Add((ushort)index);
27 | }
28 |
29 | protected int CurrentVertex
30 | {
31 | get { return vertices.Count; }
32 | }
33 |
34 | protected void InitializePrimitive(GraphicsDevice graphicsDevice)
35 | {
36 | vertexBuffer = new VertexBuffer(graphicsDevice,
37 | typeof(VertexPositionNormal),
38 | vertices.Count, BufferUsage.None);
39 |
40 | vertexBuffer.SetData(vertices.ToArray());
41 |
42 | indexBuffer = new IndexBuffer(graphicsDevice, typeof(ushort),
43 | indices.Count, BufferUsage.None);
44 |
45 | indexBuffer.SetData(indices.ToArray());
46 | }
47 |
48 | ~GeometricPrimitive()
49 | {
50 | Dispose(false);
51 | }
52 |
53 | public void Dispose()
54 | {
55 | Dispose(true);
56 | GC.SuppressFinalize(this);
57 | }
58 |
59 | protected virtual void Dispose(bool disposing)
60 | {
61 | if (disposing)
62 | {
63 | vertexBuffer?.Dispose();
64 |
65 | indexBuffer?.Dispose();
66 | }
67 | }
68 |
69 | private Matrix[] worlds = new Matrix[1];
70 | private int index = 0;
71 |
72 | public void AddWorldMatrix(Matrix matrix)
73 | {
74 | if (index == worlds.Length)
75 | {
76 | var temp = new Matrix[worlds.Length + 50];
77 | worlds.CopyTo(temp, 0);
78 | worlds = temp;
79 | }
80 |
81 | worlds[index] = matrix;
82 | index++;
83 | }
84 |
85 | public void Draw(BasicEffect effect)
86 | {
87 | if (index == 0) return;
88 |
89 | var graphicsDevice = effect.GraphicsDevice;
90 |
91 | graphicsDevice.SetVertexBuffer(vertexBuffer);
92 | graphicsDevice.Indices = indexBuffer;
93 |
94 | int primitiveCount = indices.Count / 3;
95 |
96 | for (int i = 0; i < index; i++)
97 | {
98 | effect.World = worlds[i]; effect.CurrentTechnique.Passes[0].Apply();
99 | graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, primitiveCount);
100 | }
101 |
102 | index = 0;
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Primitives3D/SpherePrimitive.cs:
--------------------------------------------------------------------------------
1 | #region File Description
2 | //-----------------------------------------------------------------------------
3 | // SpherePrimitive.cs
4 | //
5 | // Microsoft XNA Community Game Platform
6 | // Copyright (C) Microsoft Corporation. All rights reserved.
7 | //-----------------------------------------------------------------------------
8 | #endregion
9 |
10 | #region Using Statements
11 | using System;
12 | using Microsoft.Xna.Framework;
13 | using Microsoft.Xna.Framework.Graphics;
14 | #endregion
15 |
16 | namespace JitterDemo.Primitives3D
17 | {
18 | ///
19 | /// Geometric primitive class for drawing spheres.
20 | ///
21 | public class SpherePrimitive : GeometricPrimitive
22 | {
23 | ///
24 | /// Constructs a new sphere primitive, using default settings.
25 | ///
26 | public SpherePrimitive(GraphicsDevice graphicsDevice)
27 | : this(graphicsDevice, 1, 16)
28 | {
29 | }
30 |
31 | ///
32 | /// Constructs a new sphere primitive,
33 | /// with the specified size and tessellation level.
34 | ///
35 | public SpherePrimitive(GraphicsDevice graphicsDevice,
36 | float radius, int tessellation)
37 | {
38 | if (tessellation < 3)
39 | throw new ArgumentOutOfRangeException(nameof(tessellation));
40 |
41 | int verticalSegments = tessellation;
42 | int horizontalSegments = tessellation * 2;
43 |
44 | // Start with a single vertex at the bottom of the sphere.
45 | AddVertex(Vector3.Down * radius, Vector3.Down);
46 |
47 | // Create rings of vertices at progressively higher latitudes.
48 | for (int i = 0; i < verticalSegments - 1; i++)
49 | {
50 | float latitude = ((i + 1) * MathHelper.Pi
51 | / verticalSegments) - MathHelper.PiOver2;
52 |
53 | float dy = (float)Math.Sin(latitude);
54 | float dxz = (float)Math.Cos(latitude);
55 |
56 | // Create a single ring of vertices at this latitude.
57 | for (int j = 0; j < horizontalSegments; j++)
58 | {
59 | float longitude = j * MathHelper.TwoPi / horizontalSegments;
60 |
61 | float dx = (float)Math.Cos(longitude) * dxz;
62 | float dz = (float)Math.Sin(longitude) * dxz;
63 |
64 | var normal = new Vector3(dx, dy, dz);
65 |
66 | AddVertex(normal * radius, normal);
67 | }
68 | }
69 |
70 | // Finish with a single vertex at the top of the sphere.
71 | AddVertex(Vector3.Up * radius, Vector3.Up);
72 |
73 | // Create a fan connecting the bottom vertex to the bottom latitude ring.
74 | for (int i = 0; i < horizontalSegments; i++)
75 | {
76 | AddIndex(0);
77 | AddIndex(1 + ((i + 1) % horizontalSegments));
78 | AddIndex(1 + i);
79 | }
80 |
81 | // Fill the sphere body with triangles joining each pair of latitude rings.
82 | for (int i = 0; i < verticalSegments - 2; i++)
83 | {
84 | for (int j = 0; j < horizontalSegments; j++)
85 | {
86 | int nextI = i + 1;
87 | int nextJ = (j + 1) % horizontalSegments;
88 |
89 | AddIndex(1 + (i * horizontalSegments) + j);
90 | AddIndex(1 + (i * horizontalSegments) + nextJ);
91 | AddIndex(1 + (nextI * horizontalSegments) + j);
92 |
93 | AddIndex(1 + (i * horizontalSegments) + nextJ);
94 | AddIndex(1 + (nextI * horizontalSegments) + nextJ);
95 | AddIndex(1 + (nextI * horizontalSegments) + j);
96 | }
97 | }
98 |
99 | // Create a fan connecting the top vertex to the top latitude ring.
100 | for (int i = 0; i < horizontalSegments; i++)
101 | {
102 | AddIndex(CurrentVertex - 1);
103 | AddIndex(CurrentVertex - 2 - ((i + 1) % horizontalSegments));
104 | AddIndex(CurrentVertex - 2 - i);
105 | }
106 |
107 | InitializePrimitive(graphicsDevice);
108 | }
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Primitives3D/TerrainPrimitive.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Xna.Framework.Graphics;
2 | using Microsoft.Xna.Framework;
3 |
4 | namespace JitterDemo.Primitives3D
5 | {
6 | public class TerrainPrimitive : GeometricPrimitive
7 | {
8 | public delegate float TerrainFunction(int coordX,int coordZ);
9 |
10 | public float[,] heights;
11 |
12 | public TerrainPrimitive(GraphicsDevice device,TerrainFunction function)
13 | {
14 | heights = new float[100,100];
15 |
16 | for (int i = 0; i < 100; i++)
17 | {
18 | for (int e = 0; e < 100; e++)
19 | {
20 | heights[i,e]=function(i,e);
21 | }
22 | }
23 |
24 | var neighbour = new Vector3[4];
25 |
26 | for (int i = 0; i < 100; i++)
27 | {
28 | for (int e = 0; e < 100; e++)
29 | {
30 | var pos = new Vector3(i, heights[i,e], e);
31 |
32 | if (i > 0) neighbour[0] = new Vector3(i - 1, heights[i - 1,e], e);
33 | else neighbour[0] = pos;
34 |
35 | if (e > 0) neighbour[1] = new Vector3(i, heights[i,e - 1], e - 1);
36 | else neighbour[1] = pos;
37 |
38 | if (i < 99) neighbour[2] = new Vector3(i +1, heights[i + 1,e], e);
39 | else neighbour[2] = pos;
40 |
41 | if (e < 99) neighbour[3] = new Vector3(i, heights[i,e+1], e+1);
42 | else neighbour[3] = pos;
43 |
44 | var normal = Vector3.Zero;
45 |
46 | normal += Vector3.Cross(neighbour[1] - pos, neighbour[0] - pos);
47 | normal += Vector3.Cross(neighbour[2] - pos, neighbour[1] - pos);
48 | normal += Vector3.Cross(neighbour[3] - pos, neighbour[2] - pos);
49 | normal += Vector3.Cross(neighbour[0] - pos, neighbour[3] - pos);
50 | normal.Normalize();
51 |
52 | AddVertex(new Vector3(i, heights[i,e], e), normal);
53 | }
54 | }
55 |
56 | for (int i = 1; i < 100; i++)
57 | {
58 | for (int e = 1; e < 100; e++)
59 | {
60 | AddIndex(((i - 1) * 100) + e);
61 | AddIndex((i * 100) + (e - 1));
62 | AddIndex((i * 100) + e);
63 |
64 | AddIndex((i * 100) + (e - 1));
65 | AddIndex(((i - 1) * 100) + e);
66 | AddIndex(((i - 1) * 100) + (e - 1));
67 | }
68 | }
69 |
70 |
71 | InitializePrimitive(device);
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Primitives3D/VertexPositionNormal.cs:
--------------------------------------------------------------------------------
1 | #region File Description
2 | //-----------------------------------------------------------------------------
3 | // VertexPositionNormal.cs
4 | //
5 | // Microsoft XNA Community Game Platform
6 | // Copyright (C) Microsoft Corporation. All rights reserved.
7 | //-----------------------------------------------------------------------------
8 | #endregion
9 |
10 | #region Using Statements
11 | using Microsoft.Xna.Framework;
12 | using Microsoft.Xna.Framework.Graphics;
13 | #endregion
14 |
15 | namespace JitterDemo.Primitives3D
16 | {
17 | ///
18 | /// Custom vertex type for vertices that have just a
19 | /// position and a normal, without any texture coordinates.
20 | ///
21 | public struct VertexPositionNormal : IVertexType
22 | {
23 | public Vector3 Position;
24 | public Vector3 Normal;
25 |
26 | ///
27 | /// Constructor.
28 | ///
29 | public VertexPositionNormal(Vector3 position, Vector3 normal)
30 | {
31 | Position = position;
32 | Normal = normal;
33 | }
34 |
35 | ///
36 | /// A VertexDeclaration object, which contains information about the vertex
37 | /// elements contained within this struct.
38 | ///
39 | public static readonly VertexDeclaration VertexDeclaration = new VertexDeclaration
40 | (
41 | new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
42 | new VertexElement(12, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0)
43 | );
44 |
45 | VertexDeclaration IVertexType.VertexDeclaration
46 | {
47 | get { return VertexPositionNormal.VertexDeclaration; }
48 | }
49 | }
50 |
51 | public struct VertexPositionNormalColor : IVertexType
52 | {
53 | public Vector3 Position;
54 | public Vector3 Normal;
55 | public Vector3 Color;
56 |
57 | ///
58 | /// Constructor.
59 | ///
60 | public VertexPositionNormalColor(Vector3 position, Vector3 normal,Vector3 color)
61 | {
62 | Position = position;
63 | Normal = normal;
64 | Color = color;
65 | }
66 |
67 | ///
68 | /// A VertexDeclaration object, which contains information about the vertex
69 | /// elements contained within this struct.
70 | ///
71 | public static readonly VertexDeclaration VertexDeclaration = new VertexDeclaration
72 | (
73 | new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
74 | new VertexElement(12, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0),
75 | new VertexElement(24, VertexElementFormat.Vector3, VertexElementUsage.Color, 0)
76 | );
77 |
78 | VertexDeclaration IVertexType.VertexDeclaration
79 | {
80 | get { return VertexPositionNormalColor.VertexDeclaration; }
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Program.cs:
--------------------------------------------------------------------------------
1 | namespace JitterDemo
2 | {
3 | internal static class Program
4 | {
5 | private static void Main()
6 | {
7 | using (var game = new JitterDemo())
8 | {
9 | game.Run();
10 | }
11 | }
12 | }
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 | [assembly: AssemblyTitle("JitterDemo")]
8 | [assembly: AssemblyProduct("JitterDemo")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyCompany("")]
11 | [assembly: AssemblyCopyright("Copyright © 2015 Xamarin Inc.")]
12 | [assembly: AssemblyTrademark("")]
13 | [assembly: AssemblyCulture("")]
14 |
15 | // Setting ComVisible to false makes the types in this assembly not visible
16 | // to COM components. If you need to access a type in this assembly from
17 | // COM, set the ComVisible attribute to true on that type. Only Windows
18 | // assemblies support COM.
19 | [assembly: ComVisible(false)]
20 |
21 | // On Windows, the following GUID is for the ID of the typelib if this
22 | // project is exposed to COM. On other platforms, it unique identifies the
23 | // title storage container when deploying this assembly to the device.
24 | [assembly: Guid("85e384b8-fbb9-4f95-992d-6c8dbdf6e5bb")]
25 |
26 | // Version information for an assembly consists of the following four values:
27 | //
28 | // Major Version
29 | // Minor Version
30 | // Build Number
31 | // Revision
32 | //
33 | [assembly: AssemblyVersion("1.0.0.0")]
34 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/QuadDrawer.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Xna.Framework;
2 | using Microsoft.Xna.Framework.Graphics;
3 |
4 | namespace JitterDemo
5 | {
6 | public class QuadDrawer : DrawableGameComponent
7 | {
8 | private Texture2D texture;
9 | private BasicEffect effect;
10 |
11 | private readonly float size = 100.0f;
12 |
13 | private VertexPositionNormalTexture[] vertices;
14 | private int[] indices;
15 |
16 | public QuadDrawer(Game game, float size)
17 | : base(game)
18 | {
19 | this.size = size;
20 | }
21 |
22 | public override void Initialize()
23 | {
24 | BuildVertices();
25 | base.Initialize();
26 | }
27 |
28 | private void BuildVertices()
29 | {
30 | vertices = new VertexPositionNormalTexture[4];
31 | indices = new int[6];
32 |
33 | vertices[0].Position = Vector3.Forward + Vector3.Left;
34 | vertices[0].TextureCoordinate = new Vector2(0.0f, 1.0f);
35 | vertices[1].Position = Vector3.Backward + Vector3.Left;
36 | vertices[1].TextureCoordinate = new Vector2(0.0f, 0.0f);
37 | vertices[2].Position = Vector3.Forward + Vector3.Right;
38 | vertices[2].TextureCoordinate = new Vector2(1.0f, 1.0f);
39 | vertices[3].Position = Vector3.Backward + Vector3.Right;
40 | vertices[3].TextureCoordinate = new Vector2(1.0f, 0.0f);
41 |
42 | for (int i = 0; i < vertices.Length; i++)
43 | {
44 | vertices[i].Normal = Vector3.Up;
45 | vertices[i].Position *= size;
46 | vertices[i].TextureCoordinate *= size;
47 | }
48 |
49 | indices[5] = 0; indices[4] = 1; indices[3] = 2;
50 | indices[2] = 2; indices[1] = 1; indices[0] = 3;
51 | }
52 |
53 | protected override void LoadContent()
54 | {
55 | texture = Game.Content.Load("checker");
56 | effect = new BasicEffect(GraphicsDevice);
57 | effect.EnableDefaultLighting();
58 | effect.SpecularColor = new Vector3(0.1f, 0.1f, 0.1f);
59 |
60 | effect.World = Matrix.Identity;
61 | effect.TextureEnabled = true;
62 |
63 | effect.Texture = texture;
64 |
65 | base.LoadContent();
66 | }
67 |
68 | protected override void Dispose(bool disposing)
69 | {
70 | base.Dispose(disposing);
71 | }
72 |
73 | public override void Draw(GameTime gameTime)
74 | {
75 | var demo = Game as JitterDemo;
76 |
77 | GraphicsDevice.SamplerStates[0] = SamplerState.AnisotropicWrap;
78 | GraphicsDevice.DepthStencilState = DepthStencilState.Default;
79 |
80 | effect.View = demo.Camera.View;
81 | effect.Projection = demo.Camera.Projection;
82 |
83 | foreach (var pass in effect.CurrentTechnique.Passes)
84 | {
85 | pass.Apply();
86 |
87 | GraphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.TriangleList,
88 | vertices, 0, 4, indices, 0, 2);
89 | }
90 |
91 | base.Draw(gameTime);
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Scenes/BroadphaseStress.cs:
--------------------------------------------------------------------------------
1 | using Jitter.Collision.Shapes;
2 | using Jitter.Dynamics;
3 | using Jitter.LinearMath;
4 |
5 | namespace JitterDemo.Scenes
6 | {
7 | internal class BroadphaseStress : Scene
8 | {
9 | public BroadphaseStress(JitterDemo demo)
10 | : base(demo)
11 | {
12 | }
13 |
14 | public override void Build()
15 | {
16 | var shape = new BoxShape(JVector.One);
17 |
18 | // CollisionSystemBrute 170 ms
19 | // CollisionSystemSAP 7 ms
20 | // CollisionSystemPersistenSAP 1 ms
21 |
22 | for (int i = 0; i < 15; i++)
23 | {
24 | for (int e = 0; e < 15; e++)
25 | {
26 | for (int k = 0; k < 15; k++)
27 | {
28 | var b = new RigidBody(shape);
29 | Demo.World.AddBody(b);
30 | b.Position = new JVector(i, e, k) * 2.0f;
31 | b.AffectedByGravity = false;
32 | }
33 | }
34 | }
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Scenes/Cardhouse.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using Microsoft.Xna.Framework;
4 | using Jitter.Collision.Shapes;
5 | using Jitter.Dynamics;
6 | using Jitter.LinearMath;
7 | using System.Diagnostics;
8 |
9 | namespace JitterDemo.Scenes
10 | {
11 | internal class CardHouse : Scene
12 | {
13 | public CardHouse(JitterDemo demo) : base(demo) { }
14 |
15 | private static JVector cardHouseStartingPosition = new JVector(0, 0, 0);
16 | private const int cardHouseLayers = 10; // starting from 1
17 |
18 | private const double cardThickness = 0.05;
19 | private const double cardHeight = 3;
20 | private const double cardWidth = 2;
21 | private const float degree = 75;
22 |
23 | private const float angle = degree * (float)Math.PI / 180f;
24 | private const float oppositeAngle = (float)Math.PI - angle;
25 | private static readonly double cardThicknessVerticalMargin = cardThickness / 2 * Math.Sin(MathHelper.PiOver2 - angle);
26 | private static readonly double cardThicknessHorizontalMargin = cardThickness / 2 * Math.Cos(MathHelper.PiOver2 - angle);
27 | private static readonly float layerHeight = (float)((cardHeight * Math.Sin(angle)) + (2 * cardThicknessVerticalMargin));
28 | private static readonly float cardSpacing = (float)((cardHeight * Math.Cos(angle)) + (2 * cardThicknessHorizontalMargin));
29 |
30 | public override void Build()
31 | {
32 | Demo.World.ContactSettings.AllowedPenetration = 0.001f;
33 | Demo.World.ContactSettings.BiasFactor = 0.05f;
34 |
35 | // Demo.World.SetIterations(60, 5);
36 | AddGround();
37 |
38 | for (int layer = 0; layer < cardHouseLayers; layer++)
39 | {
40 | int layerCards = (cardHouseLayers - layer) * 2;
41 |
42 | AddCardLayer(
43 | cardHouseStartingPosition
44 | + new JVector(cardSpacing * layer, (layerHeight + (float)(2 * cardThickness)) * layer, 0),
45 | layerCards);
46 | }
47 | }
48 |
49 | private void AddCardLayer(JVector startPosition, int angledCards)
50 | {
51 | Debug.Assert(angledCards % 2 == 0);
52 |
53 | foreach (int i in Enumerable.Range(0, angledCards))
54 | {
55 | AddCard(
56 | startPosition + new JVector(cardSpacing * i, layerHeight / 2f, 0),
57 | (i % 2 == 0) ? angle : oppositeAngle);
58 | }
59 |
60 | for (float distance = 1.5f; distance < angledCards - 0.5; distance += 4)
61 | {
62 | AddCard(startPosition + new JVector(cardSpacing * distance, layerHeight, 0), 0);
63 | }
64 |
65 | for (float distance = 3.5f; distance < angledCards - 0.5; distance += 4)
66 | {
67 | AddCard(startPosition + new JVector(cardSpacing * distance, layerHeight + (float)cardThickness, 0), 0);
68 | }
69 | }
70 |
71 | private void AddCard(JVector position, float rollOrientation)
72 | {
73 | var body = new RigidBody(new BoxShape((float)cardHeight, (float)cardThickness, (float)cardWidth))
74 | {
75 | Mass = 0.5f
76 | };
77 | body.Material.Restitution = 0;
78 | body.Position = position;
79 | if (rollOrientation != 0)
80 | {
81 | body.Orientation = JMatrix.CreateFromYawPitchRoll(0, 0, rollOrientation);
82 | }
83 |
84 | Demo.World.AddBody(body);
85 | }
86 | }
87 | }
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Scenes/Cloth.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using Jitter.Collision.Shapes;
6 | using Jitter.Dynamics;
7 | using Jitter.LinearMath;
8 | using Jitter.Forces;
9 | using Jitter.Dynamics.Constraints;
10 |
11 | namespace JitterDemo.Scenes
12 | {
13 | public class Cloth : Scene
14 | {
15 |
16 | public Cloth(JitterDemo demo)
17 | : base(demo)
18 | {
19 |
20 |
21 | }
22 |
23 | public override void Build()
24 | {
25 |
26 | AddGround();
27 |
28 | // we need some of them!
29 | Demo.World.SetIterations(5);
30 |
31 | PseudoCloth pc = new PseudoCloth(Demo.World, 20,20, 0.5f);
32 |
33 | BoxShape boxShape = new BoxShape(JVector.One);
34 |
35 | RigidBody[] boxes = new RigidBody[4];
36 |
37 | int size = 19;
38 |
39 | for(int i=0;i<4;i++)
40 | {
41 | boxes[i] = new RigidBody(boxShape);
42 | boxes[i].Position = new JVector(i % 2 == 0 ? 10.0f : -0.5f, 10.5f, (i < 2) ? 10.0f : -0.5f);
43 | // Demo.World.AddBody(boxes[i]);
44 |
45 |
46 |
47 | if (i == 0)
48 | {
49 |
50 | pc.GetCorner(size, size).IsStatic = true;
51 | }
52 | else if (i == 1)
53 | {
54 |
55 | pc.GetCorner(size, 0).IsStatic = true;
56 | }
57 | else if (i == 2)
58 | {
59 |
60 | pc.GetCorner(0, size).IsStatic = true;
61 | }
62 | else if (i == 3)
63 | {
64 |
65 | pc.GetCorner(0, 0).IsStatic = true;
66 | }
67 |
68 | boxes[i].IsStatic = true;
69 | }
70 |
71 | RigidBody sphereBody = new RigidBody(new SphereShape(2.0f));
72 | Demo.World.AddBody(sphereBody);
73 | sphereBody.Mass = 10.0f;
74 | sphereBody.Position = new JVector(5, 20, 5);
75 |
76 | //ConvexHullObject2 obj2 = new ConvexHullObject2(this.Demo);
77 | //Demo.Components.Add(obj2);
78 |
79 | //obj2.body.Position = new JVector(5, 30, 5);
80 | //Demo.World.AddBody(obj2.body);
81 |
82 | }
83 |
84 | public override void Destroy()
85 | {
86 | RemoveGround();
87 | this.Demo.World.Clear();
88 | }
89 |
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Scenes/ConvexDecomposition.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using Jitter.LinearMath;
5 | #if WINDOWS
6 |
7 | using System.Globalization;
8 | using Jitter.Collision.Shapes;
9 | using Jitter.Dynamics;
10 |
11 | namespace JitterDemo.Scenes
12 | {
13 | internal class ConvexDecomposition : Scene
14 | {
15 | public ConvexDecomposition(JitterDemo demo)
16 | : base(demo)
17 | {
18 | }
19 |
20 | public override void Build()
21 | {
22 | AddGround();
23 |
24 | var shapes = BuildFromHACDTestObjFile(@"Content/ConvexDecomposition.obj");
25 |
26 | var transformedShapes
27 | = new CompoundShape.TransformedShape[shapes.Count];
28 |
29 | for (int i = 0; i < shapes.Count; i++)
30 | {
31 | transformedShapes[i] = new CompoundShape.TransformedShape
32 | {
33 | Shape = shapes[i],
34 | Orientation = JMatrix.Identity,
35 | Position = -1.0f * shapes[i].Shift
36 | };
37 | }
38 |
39 | // Create one compound shape
40 | var cs = new CompoundShape(transformedShapes);
41 |
42 | for (int i = 0; i < 1; i++)
43 | {
44 | var compoundBody = new RigidBody(cs)
45 | {
46 | EnableDebugDraw = true,
47 | Position = new JVector(0, 5 + (i * 10), 0) - cs.Shift
48 | };
49 | Demo.World.AddBody(compoundBody);
50 | }
51 |
52 | // Create several single bodies.
53 | for (int i = 0; i < shapes.Count; i++)
54 | {
55 | var body = new RigidBody(shapes[i])
56 | {
57 | Position = (-1.0f * shapes[i].Shift) + new JVector(-10, 5, 0),
58 | EnableDebugDraw = true
59 | };
60 | Demo.World.AddBody(body);
61 | }
62 |
63 | for (int i = 0; i < shapes.Count; i++)
64 | {
65 | var body = new RigidBody(shapes[i])
66 | {
67 | Position = (-1.0f * shapes[i].Shift) + new JVector(-20, 5, 0),
68 | EnableDebugDraw = true,
69 | IsStatic = true
70 | };
71 | Demo.World.AddBody(body);
72 | }
73 | }
74 |
75 | ///
76 | /// A really stupid parser for convex decomposed files made by testhacd.exe (see Other\hacdtest)
77 | ///
78 | public List BuildFromHACDTestObjFile(string path)
79 | {
80 | var shapes = new List();
81 |
82 | string[] lines = File.ReadAllLines(path);
83 | Char[] splitter = new Char [] {' '};
84 |
85 | var convexPoints = new List();
86 |
87 | for (int i = 0; i < lines.Length; i++)
88 | {
89 | string line = lines[i];
90 |
91 | if (line.StartsWith("v"))
92 | {
93 | string[] values = line.Split(splitter);
94 |
95 | var vertex = new JVector(float.Parse(values[1], NumberFormatInfo.InvariantInfo),
96 | float.Parse(values[2], NumberFormatInfo.InvariantInfo),
97 | float.Parse(values[3], NumberFormatInfo.InvariantInfo));
98 |
99 | convexPoints.Add(vertex * 5f);
100 | }
101 |
102 | if(line.StartsWith("#"))
103 | {
104 | if(convexPoints.Count > 0)
105 | {
106 | var copyVertex = new List(convexPoints);
107 | convexPoints.Clear();
108 |
109 | var cvhs = new ConvexHullShape(copyVertex);
110 |
111 | if(cvhs.Mass > 0.001f) shapes.Add(cvhs);
112 | }
113 | }
114 | }
115 |
116 | return shapes;
117 | }
118 | }
119 | }
120 |
121 | #endif
122 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Scenes/CylinderWall.cs:
--------------------------------------------------------------------------------
1 | using Jitter.Collision.Shapes;
2 | using Jitter.Dynamics;
3 | using Jitter.LinearMath;
4 |
5 | namespace JitterDemo.Scenes
6 | {
7 | internal class CylinderWall : Scene
8 | {
9 | public CylinderWall(JitterDemo demo)
10 | : base(demo)
11 | {
12 | }
13 |
14 | public override void Build()
15 | {
16 | AddGround();
17 |
18 | for (int i = 0; i < 20; i++)
19 | {
20 | for (int e = 0; e < 20; e++)
21 | {
22 | var body = new RigidBody(new CylinderShape(1.0f, 0.5f))
23 | {
24 | Position = new JVector((e * 1.01f) + ((i % 2 == 0) ? 0.5f : 0.0f), 0.5f + (i * 1.0f), 0.0f)
25 | };
26 | Demo.World.AddBody(body);
27 | }
28 | }
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Scenes/Domino.cs:
--------------------------------------------------------------------------------
1 | using Jitter.Collision.Shapes;
2 | using Jitter.Dynamics;
3 | using Jitter.LinearMath;
4 |
5 | namespace JitterDemo.Scenes
6 | {
7 | public class Domino : Scene
8 | {
9 | public Domino(JitterDemo demo) : base(demo)
10 | {
11 | }
12 |
13 | public override void Build()
14 | {
15 | //this.Demo.World.Solver = Jitter.World.SolverType.Sequential;
16 |
17 | AddGround();
18 |
19 | var bShape = new BoxShape(0.5f, 4.0f, 2.0f);
20 |
21 | for (int i = 0; i < 10; i++)
22 | {
23 | var body = new RigidBody(bShape)
24 | {
25 | Position = new JVector(i * 2.0f, 2, 0)
26 | };
27 | Demo.World.AddBody(body);
28 | }
29 |
30 | ground.Material.Restitution = 0.0f;
31 | ground.Material.StaticFriction = 0.4f;
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Scenes/EmptyScene.cs:
--------------------------------------------------------------------------------
1 | namespace JitterDemo.Scenes
2 | {
3 | public class EmptyScene : Scene
4 | {
5 | public EmptyScene(JitterDemo demo)
6 | : base(demo)
7 | {
8 | }
9 |
10 | public override void Build()
11 | {
12 | AddGround();
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Scenes/Jenga.cs:
--------------------------------------------------------------------------------
1 | using Jitter.Collision.Shapes;
2 | using Jitter.Dynamics;
3 | using Jitter.LinearMath;
4 |
5 | namespace JitterDemo.Scenes
6 | {
7 | internal class Jenga : Scene
8 | {
9 | public Jenga(JitterDemo demo)
10 | : base(demo)
11 | {
12 | }
13 |
14 | public override void Build()
15 | {
16 | AddGround();
17 |
18 | for (int i = 0; i < 15; i++)
19 | {
20 | bool even = i % 2 == 0;
21 |
22 | for (int e = 0; e < 3; e++)
23 | {
24 | var size = even ? new JVector(1, 1, 3) : new JVector(3, 1, 1);
25 | var body = new RigidBody(new BoxShape(size))
26 | {
27 | Position = new JVector(3.0f + (even ? e : 1.0f), i + 0.5f, -13.0f + (even ? 1.0f : e))
28 | };
29 |
30 | Demo.World.AddBody(body);
31 | }
32 | }
33 |
34 | //BoxShape bs = new BoxShape(10, 10, 0.01f);
35 | //RigidBody bb = new RigidBody(bs);
36 |
37 | //bb.Position = new JVector(10, 5, 0);
38 |
39 | //Demo.World.AddBody(bb);
40 | //bb.IsStatic = true;
41 |
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Scenes/NewtonCradle.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using Jitter.Collision.Shapes;
6 | using Jitter.Dynamics;
7 | using Jitter.LinearMath;
8 | using Jitter.Dynamics.Constraints;
9 |
10 | namespace JitterDemo.Scenes
11 | {
12 | public class NewtonCradle : Scene
13 | {
14 |
15 | public NewtonCradle(JitterDemo demo)
16 | : base(demo)
17 | {
18 | }
19 |
20 | public override void Build()
21 | {
22 | this.Demo.World.Solver = Jitter.World.SolverType.Sequential;
23 |
24 | AddGround();
25 |
26 | RigidBody boxb = new RigidBody(new BoxShape(7,1,2));
27 | boxb.Position = new JVector(3.0f,12,0);
28 | this.Demo.World.AddBody(boxb);
29 | boxb.Tag = BodyTag.DontDrawMe;
30 |
31 | boxb.IsStatic = true;
32 |
33 | this.Demo.World.Solver = Jitter.World.SolverType.Sequential;
34 | //this.Demo.World.SetDampingFactors(1.0f, 1.0f);
35 |
36 | SphereShape shape = new SphereShape(0.501f);
37 |
38 | for (int i = 0; i < 7; i++)
39 | {
40 | RigidBody body = new RigidBody(shape);
41 | body.Position = new JVector(i, 6, 0);
42 |
43 | DistanceConstraint dc1 = new DistanceConstraint(boxb, body, body.Position + JVector.Up * 6 + JVector.Backward * 5 + JVector.Down * 0.5f, body.Position);
44 | dc1.Softness = 1.0f;
45 |
46 | DistanceConstraint dc2 = new DistanceConstraint(boxb, body, body.Position + JVector.Up * 6 + JVector.Forward * 5 + JVector.Down * 0.5f, body.Position);
47 | dc2.Softness = 1.0f;
48 |
49 | dc1.BiasFactor = dc2.BiasFactor = 0.8f;
50 |
51 | dc1.IsMaxDistance = dc2.IsMaxDistance = false;
52 |
53 | this.Demo.World.AddBody(body);
54 | this.Demo.World.AddConstraint(dc1);
55 | this.Demo.World.AddConstraint(dc2);
56 |
57 | body.Restitution = 1.0f;
58 | body.StaticFriction = 1.0f;
59 |
60 | // this.Demo.World.SetDampingFactors(1.0f, 1.0f);
61 | }
62 |
63 | //for (int i = 0; i < 5; i++)
64 | //{
65 | // RigidBody sBody = new RigidBody(new SphereShape(0.5f));
66 | // sBody.Position = new JVector(0, 0.5f, i);
67 | // this.Demo.World.AddBody(sBody);
68 | // sBody.Restitution = 1.0f;
69 | // sBody.Friction = 0.0f;
70 | //}
71 |
72 | //for (int i = 0; i < 3; i++)
73 | //{
74 | // RigidBody sBody = new RigidBody(new SphereShape(0.5f));
75 | // sBody.Position = new JVector(0, 0.5f, 10 + i);
76 | // this.Demo.World.AddBody(sBody);
77 | // sBody.LinearVelocity = JVector.Forward * 3;
78 | // sBody.Restitution = 1.0f;
79 | // sBody.Friction = 0.0f;
80 | //}
81 |
82 |
83 |
84 | //this.Demo.World.SetDampingFactors(1, 1);
85 |
86 |
87 | }
88 |
89 | public override void Destroy()
90 | {
91 | this.Demo.World.Solver = Jitter.World.SolverType.Simultaneous;
92 |
93 | RemoveGround();
94 | this.Demo.World.Clear();
95 | }
96 |
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Scenes/PrismaticJointTest.cs:
--------------------------------------------------------------------------------
1 | using Jitter.Collision.Shapes;
2 | using Jitter.Dynamics;
3 | using Jitter.LinearMath;
4 | using Jitter.Dynamics.Joints;
5 |
6 | namespace JitterDemo.Scenes
7 | {
8 | public class PrismaticJointTest : Scene
9 | {
10 | public PrismaticJointTest(JitterDemo demo)
11 | : base(demo)
12 | {
13 | }
14 |
15 | public override void Build()
16 | {
17 | AddGround();
18 |
19 | var body1 = new RigidBody(new BoxShape(1, 1, 1));
20 | var body2 = new RigidBody(new BoxShape(1, 1, 1));
21 |
22 | body1.Position = new JVector(0, 7, 0);
23 | body2.Position = new JVector(0, 4, 0);
24 |
25 | // add a prismatic joint.
26 | // the minimum allowed distance is 3
27 | // the maximum allowed distance is also 3
28 | // => the body should be fixed on the slider
29 | var pj = new PrismaticJoint(Demo.World, body1, body2, 3, 3);
30 |
31 | // but we set very heigh softness (1.0f) to the minimum distance
32 | // so we have something like a suspension effect.
33 | pj.MaximumDistanceConstraint.Softness = 0.0f;
34 | pj.MinimumDistanceConstraint.Softness = 1.0f;
35 | pj.Activate();
36 |
37 | Demo.World.AddBody(body1);
38 | Demo.World.AddBody(body2);
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Scenes/Pyramid.cs:
--------------------------------------------------------------------------------
1 | using Jitter.Collision.Shapes;
2 | using Jitter.Dynamics;
3 | using Jitter.LinearMath;
4 |
5 | namespace JitterDemo.Scenes
6 | {
7 | internal class Pyramid : Scene
8 | {
9 | public Pyramid(JitterDemo demo)
10 | : base(demo)
11 | {
12 | }
13 |
14 | public override void Build()
15 | {
16 | AddGround();
17 |
18 | for (int i = 0; i < 30; i++)
19 | {
20 | for (int e = i; e < 30; e++)
21 | {
22 | var body = new RigidBody(new BoxShape(new JVector(1.0f, 1.0f, 1.0f)))
23 | {
24 | Position = new JVector(((e - (i * 0.5f)) * 1.01f) + 7, 0.5f + (i * 1.0f), 3.0f)
25 | };
26 | Demo.World.AddBody(body);
27 | //body.IsParticle = true;
28 | //body.AffectedByGravity = false;
29 | body.Material.Restitution = 0.0f;
30 | }
31 | }
32 |
33 | //BoxShape shape = new BoxShape(JVector.One);
34 |
35 | //for (int i = 0; i < 20; i++)
36 | //{
37 | // for (int e = 0; e < 20; e++)
38 | // {
39 | // for (int k = 0; k < 20; k++)
40 | // {
41 | // RigidBody b = new RigidBody(shape);
42 | // Demo.World.AddBody(b);
43 | // b.Position = new JVector(i, e, k) * 2.0f;
44 | // b.AffectedByGravity = false;
45 | // }
46 | // }
47 | //}
48 |
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Scenes/Ragdoll.cs:
--------------------------------------------------------------------------------
1 | using Jitter;
2 | using Jitter.Collision.Shapes;
3 | using Jitter.Dynamics;
4 | using Jitter.LinearMath;
5 | using Jitter.Dynamics.Constraints;
6 | using Jitter.Dynamics.Joints;
7 |
8 | namespace JitterDemo.Scenes
9 | {
10 | internal class Ragdoll : Scene
11 | {
12 | public Ragdoll(JitterDemo demo)
13 | : base(demo)
14 | {
15 | }
16 |
17 | public override void Build()
18 | {
19 | AddGround();
20 |
21 | //RigidBody body = new RigidBody(new BoxShape(JVector.One * 3));
22 | //body.Position = new JVector(0, 5, 0);
23 | //body.UseUserMassProperties(JMatrix.Zero, 1f, true);
24 | //Demo.World.AddBody(body);
25 |
26 | for (int i = 3; i < 8; i++)
27 | {
28 | for (int e = 3; e < 8; e++)
29 | {
30 | BuildRagdoll(Demo.World, new JVector((i * 6) - 25, 5, (e * 6) - 25));
31 | }
32 | }
33 | }
34 |
35 | public void BuildRagdoll(World world, JVector position)
36 | {
37 | // the torso
38 | var torso = new RigidBody(new BoxShape(1.5f, 3, 0.5f))
39 | {
40 | Position = position
41 | };
42 |
43 | // the head
44 | var head = new RigidBody(new SphereShape(0.5f))
45 | {
46 | Position = position + new JVector(0, 2.1f, 0)
47 | };
48 |
49 | // connect head and torso
50 | var headTorso = new PointPointDistance(head, torso,
51 | position + new JVector(0, 1.6f, 0), position + new JVector(0, 1.5f, 0));
52 |
53 | var arm1 = new RigidBody(new CapsuleShape(0.8f, 0.2f))
54 | {
55 | Position = position + new JVector(1.0f, 0.75f, 0)
56 | };
57 |
58 | var arm2 = new RigidBody(new CapsuleShape(0.8f, 0.2f))
59 | {
60 | Position = position + new JVector(-1.0f, 0.75f, 0)
61 | };
62 |
63 | var lowerarm1 = new RigidBody(new CapsuleShape(0.6f, 0.2f))
64 | {
65 | Position = position + new JVector(1.0f, -0.45f, 0)
66 | };
67 |
68 | var lowerarm2 = new RigidBody(new CapsuleShape(0.6f, 0.2f))
69 | {
70 | Position = position + new JVector(-1.0f, -0.45f, 0)
71 | };
72 |
73 | var arm1torso = new PointOnPoint(arm1, torso, position + new JVector(0.9f, 1.4f, 0));
74 | var arm2torso = new PointOnPoint(arm2, torso, position + new JVector(-0.9f, 1.4f, 0));
75 |
76 | var arm1Hinge = new HingeJoint(world, arm1, lowerarm1, position + new JVector(1.0f, 0.05f, 0), JVector.Right);
77 | var arm2Hinge = new HingeJoint(world, arm2, lowerarm2, position + new JVector(-1.0f, 0.05f, 0), JVector.Right);
78 |
79 | var leg1 = new RigidBody(new CapsuleShape(1.0f, 0.3f))
80 | {
81 | Position = position + new JVector(-0.5f, -2.4f, 0)
82 | };
83 |
84 | var leg2 = new RigidBody(new CapsuleShape(1.0f, 0.3f))
85 | {
86 | Position = position + new JVector(0.5f, -2.4f, 0)
87 | };
88 |
89 | var leg1torso = new PointOnPoint(leg1, torso, position + new JVector(-0.5f, -1.6f, 0));
90 | var leg2torso = new PointOnPoint(leg2, torso, position + new JVector(+0.5f, -1.6f, 0));
91 |
92 | var lowerleg1 = new RigidBody(new CapsuleShape(0.8f, 0.3f))
93 | {
94 | Position = position + new JVector(-0.5f, -4.0f, 0)
95 | };
96 |
97 | var lowerleg2 = new RigidBody(new CapsuleShape(0.8f, 0.3f))
98 | {
99 | Position = position + new JVector(+0.5f, -4.0f, 0)
100 | };
101 |
102 | var leg1Hinge = new HingeJoint(world, leg1, lowerleg1, position + new JVector(-0.5f, -3.35f, 0), JVector.Right);
103 | var leg2Hinge = new HingeJoint(world, leg2, lowerleg2, position + new JVector(0.5f, -3.35f, 0), JVector.Right);
104 |
105 | lowerleg1.IsActive = false;
106 | lowerleg2.IsActive = false;
107 | leg1.IsActive = false;
108 | leg2.IsActive = false;
109 | head.IsActive = false;
110 | torso.IsActive = false;
111 | arm1.IsActive = false;
112 | arm2.IsActive = false;
113 | lowerarm1.IsActive = false;
114 | lowerarm2.IsActive = false;
115 |
116 | world.AddBody(head); world.AddBody(torso);
117 | world.AddBody(arm1); world.AddBody(arm2);
118 | world.AddBody(lowerarm1); world.AddBody(lowerarm2);
119 | world.AddBody(leg1); world.AddBody(leg2);
120 | world.AddBody(lowerleg1); world.AddBody(lowerleg2);
121 |
122 | arm1Hinge.Activate(); arm2Hinge.Activate();
123 | leg1Hinge.Activate(); leg2Hinge.Activate();
124 |
125 | world.AddConstraint(headTorso);
126 | world.AddConstraint(arm1torso);
127 | world.AddConstraint(arm2torso);
128 | world.AddConstraint(leg1torso);
129 | world.AddConstraint(leg2torso);
130 | }
131 | }
132 | }
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Scenes/Restitution.cs:
--------------------------------------------------------------------------------
1 | using Jitter.Collision.Shapes;
2 | using Jitter.Dynamics;
3 | using Jitter.LinearMath;
4 |
5 | namespace JitterDemo.Scenes
6 | {
7 | internal class Restitution : Scene
8 | {
9 | public Restitution(JitterDemo demo)
10 | : base(demo)
11 | {
12 | }
13 |
14 | public override void Build()
15 | {
16 | AddGround();
17 |
18 | for (int i = 0; i < 11; i++)
19 | {
20 | var box = new RigidBody(new BoxShape(1,0.01f,1));
21 | Demo.World.AddBody(box);
22 | var boxPos = new JVector(-15 + (i * 3) + 1, 5, 0);
23 |
24 | box.Position = boxPos;
25 | box.IsStatic = true;
26 |
27 | var sphere = new RigidBody(new SphereShape(0.5f));
28 | Demo.World.AddBody(sphere);
29 |
30 | sphere.Position = boxPos + (JVector.Up * 30);
31 | sphere.EnableSpeculativeContacts = true;
32 |
33 | // set restitution
34 | sphere.Material.Restitution = box.Material.Restitution = 1.0f / 10.0f * i;
35 | sphere.LinearVelocity = new JVector(0, 0, 0);
36 |
37 |
38 | sphere.Damping = RigidBody.DampingType.Angular;
39 | }
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Scenes/Rope.cs:
--------------------------------------------------------------------------------
1 | using Jitter.Collision.Shapes;
2 | using Jitter.Dynamics;
3 | using Jitter.LinearMath;
4 | using Jitter.Dynamics.Constraints;
5 |
6 | namespace JitterDemo.Scenes
7 | {
8 | internal class Rope : Scene
9 | {
10 | public Rope(JitterDemo demo)
11 | : base(demo)
12 | {
13 | }
14 |
15 | public override void Build()
16 | {
17 | AddGround();
18 |
19 | RigidBody last = null;
20 |
21 | for (int i = 0; i < 12; i++)
22 | {
23 | var body = new RigidBody(new BoxShape(JVector.One))
24 | {
25 | Position = new JVector((i * 1.5f) - 20, 0.5f, 0)
26 | };
27 |
28 | var jpos2 = body.Position;
29 |
30 | Demo.World.AddBody(body);
31 | body.Update();
32 |
33 | if (last != null)
34 | {
35 | var jpos3 = last.Position;
36 |
37 | JVector.Subtract(ref jpos2, ref jpos3, out var dif);
38 | JVector.Multiply(ref dif, 0.5f, out dif);
39 | JVector.Subtract(ref jpos2, ref dif, out dif);
40 |
41 | Constraint cons = new PointOnPoint(last, body, dif);
42 | Demo.World.AddConstraint(cons);
43 | }
44 |
45 | last = body;
46 | }
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Scenes/Scene.cs:
--------------------------------------------------------------------------------
1 | using Jitter.Dynamics;
2 | using Jitter.LinearMath;
3 | using Jitter.Collision.Shapes;
4 | using JitterDemo.Vehicle;
5 |
6 | namespace JitterDemo.Scenes
7 | {
8 | public abstract class Scene
9 | {
10 | public JitterDemo Demo { get; }
11 |
12 | public Scene(JitterDemo demo)
13 | {
14 | Demo = demo;
15 | }
16 |
17 | public abstract void Build();
18 |
19 | private QuadDrawer quadDrawer = null;
20 | protected RigidBody ground = null;
21 | protected CarObject car = null;
22 |
23 | public void AddGround()
24 | {
25 | ground = new RigidBody(new BoxShape(new JVector(200, 20, 200)))
26 | {
27 | Position = new JVector(0, -10, 0),
28 | Tag = BodyTag.DontDrawMe,
29 | IsStatic = true
30 | };
31 | Demo.World.AddBody(ground);
32 | //ground.Restitution = 1.0f;
33 | ground.Material.KineticFriction = 0.0f;
34 |
35 | quadDrawer = new QuadDrawer(Demo,100);
36 | Demo.Components.Add(quadDrawer);
37 | }
38 |
39 | public void RemoveGround()
40 | {
41 | Demo.World.RemoveBody(ground);
42 | Demo.Components.Remove(quadDrawer);
43 | quadDrawer.Dispose();
44 | }
45 |
46 | public void AddCar(JVector position)
47 | {
48 | car = new CarObject(Demo);
49 | Demo.Components.Add(car);
50 |
51 | car.carBody.Position = position;
52 | }
53 |
54 | public void RemoveCar()
55 | {
56 | Demo.World.RemoveBody(car.carBody);
57 | Demo.Components.Remove(quadDrawer);
58 | Demo.Components.Remove(car);
59 | }
60 |
61 | public virtual void Draw() { }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Scenes/SoftBodyJenga.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Jitter.Collision.Shapes;
3 | using Jitter.Dynamics;
4 | using Jitter.LinearMath;
5 | using Microsoft.Xna.Framework.Graphics;
6 | using Jitter.Collision;
7 |
8 | namespace JitterDemo.Scenes
9 | {
10 | internal class SoftBodyJenga : Scene
11 | {
12 | public SoftBodyJenga(JitterDemo demo)
13 | : base(demo)
14 | {
15 | }
16 |
17 | private void RemoveDuplicateVertices(List indices,
18 | List vertices)
19 | {
20 | var unique = new Dictionary(vertices.Count);
21 | var tbr = new Stack(vertices.Count / 3);
22 |
23 | // get all unique vertices and their indices
24 | for (int i = 0; i < vertices.Count; i++)
25 | {
26 | if (!unique.ContainsKey(vertices[i]))
27 | unique.Add(vertices[i], unique.Count);
28 | else tbr.Push(i);
29 | }
30 |
31 | // reconnect indices
32 | for (int i = 0; i < indices.Count; i++)
33 | {
34 | var tvi = indices[i];
35 |
36 | tvi.I0 = unique[vertices[tvi.I0]];
37 | tvi.I1 = unique[vertices[tvi.I1]];
38 | tvi.I2 = unique[vertices[tvi.I2]];
39 |
40 | indices[i] = tvi;
41 | }
42 |
43 | // remove duplicate vertices
44 | while (tbr.Count > 0) vertices.RemoveAt(tbr.Pop());
45 |
46 | unique.Clear();
47 | }
48 |
49 | public override void Build()
50 | {
51 | AddGround();
52 |
53 | for (int i = 0; i < 15; i++)
54 | {
55 | bool even = i % 2 == 0;
56 |
57 | for (int e = 0; e < 3; e++)
58 | {
59 | var size = even ? new JVector(1, 1, 3) : new JVector(3, 1, 1);
60 | var body = new RigidBody(new BoxShape(size))
61 | {
62 | Position = new JVector(3.0f + (even ? e : 1.0f), i + 0.5f, -5.0f + (even ? 1.0f : e))
63 | };
64 |
65 | Demo.World.AddBody(body);
66 | }
67 | }
68 |
69 | var model = Demo.Content.Load("torus");
70 |
71 | var indices = new List();
72 | var vertices = new List();
73 |
74 | ConvexHullObject.ExtractData(vertices, indices, model);
75 | RemoveDuplicateVertices(indices, vertices);
76 |
77 | var softBody = new SoftBody(indices, vertices);
78 |
79 | softBody.Translate(new JVector(10, 5, 0));
80 | softBody.Pressure = 1000.0f;
81 | softBody.SetSpringValues(0.2f, 0.005f);
82 | //softBody.SelfCollision = true; ;
83 |
84 | Demo.World.AddBody(softBody);
85 |
86 | var cloth = new SoftBody(20,20,0.4f);
87 |
88 | // ##### Uncomment for selfcollision, all 3 lines
89 | //cloth.SelfCollision = true;
90 | //cloth.TriangleExpansion = 0.05f;
91 | //cloth.VertexExpansion = 0.05f;
92 |
93 | cloth.Translate(new JVector(0, 10, 10));
94 |
95 | cloth.Material.KineticFriction = 0.9f;
96 | cloth.Material.StaticFriction = 0.95f;
97 |
98 | cloth.VertexBodies[0].IsStatic = true;
99 | cloth.VertexBodies[380].IsStatic = true;
100 | cloth.VertexBodies[19].IsStatic = true;
101 | cloth.VertexBodies[399].IsStatic = true;
102 |
103 | cloth.SetSpringValues(SoftBody.SpringType.EdgeSpring, 0.1f, 0.01f);
104 | cloth.SetSpringValues(SoftBody.SpringType.ShearSpring, 0.1f, 0.03f);
105 | cloth.SetSpringValues(SoftBody.SpringType.BendSpring, 0.1f, 0.03f);
106 |
107 | // ###### Uncomment here for a better visualization
108 | // Demo.Components.Add(new ClothObject(Demo, cloth));
109 |
110 | Demo.World.AddBody(cloth);
111 | }
112 | }
113 | }
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Scenes/Terrain.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.Xna.Framework;
3 | using Jitter.Collision.Shapes;
4 | using Jitter.Dynamics;
5 | using Jitter.LinearMath;
6 |
7 | namespace JitterDemo.Scenes
8 | {
9 | public class Terrain : Scene
10 | {
11 | private Primitives3D.TerrainPrimitive terrain;
12 |
13 | public Terrain(JitterDemo demo)
14 | : base(demo)
15 | {
16 | }
17 |
18 | public override void Build()
19 | {
20 | terrain = new Primitives3D.TerrainPrimitive(Demo.GraphicsDevice,
21 | (a, b) =>
22 | {
23 | return (float)(Math.Cos(a * 0.2f) * Math.Sin(b * 0.2f) * 2.0f);
24 | });
25 |
26 | var shape = new TerrainShape(terrain.heights, 1.0f, 1.0f);
27 |
28 | var body = new RigidBody(shape);
29 | body.Position -= new JVector(50, 0, 50);
30 | body.IsStatic = true;
31 | body.Tag = BodyTag.DontDrawMe;
32 | //body.EnableDebugDraw = true;
33 | Demo.World.AddBody(body);
34 |
35 | AddCar(new JVector(0, 4, 0));
36 | }
37 |
38 | public override void Draw()
39 | {
40 | terrain.AddWorldMatrix(Matrix.CreateTranslation(-50, 0, -50));
41 | Demo.BasicEffect.DiffuseColor = Color.Red.ToVector3();
42 | terrain.Draw(Demo.BasicEffect);
43 | base.Draw();
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Scenes/Tower.cs:
--------------------------------------------------------------------------------
1 | using Jitter;
2 | using Microsoft.Xna.Framework;
3 | using Jitter.Collision.Shapes;
4 | using Jitter.Dynamics;
5 |
6 | namespace JitterDemo.Scenes
7 | {
8 | internal class Tower : Scene
9 | {
10 | public Tower(JitterDemo demo)
11 | : base(demo)
12 | {
13 | }
14 |
15 | public override void Build()
16 | {
17 | AddGround();
18 |
19 | var world = Demo.World;
20 |
21 | var halfRotationStep = Matrix.CreateRotationY(MathHelper.Pi * 2.0f / 24.0f);
22 | var fullRotationStep = halfRotationStep * halfRotationStep;
23 | var orientation = Matrix.Identity;
24 |
25 | var shape = new BoxShape(2, 1, 1);
26 |
27 | //for (int i = 0; i < 15; i++)
28 | //{
29 | // for (int e = 0; e < 15; e++)
30 | // {
31 | // for (int k = 0; k < 15; k++)
32 | // {
33 | // RigidBody b = new RigidBody(shape);
34 | // Demo.World.AddBody(b);
35 | // b.Position = new JVector(i, e, k) * 4.0f;
36 | // b.AffectedByGravity = true;
37 | // }
38 | // }
39 | //}
40 |
41 | for (int e = 0; e < 40; e++)
42 | {
43 | orientation *= halfRotationStep;
44 |
45 | for (int i = 0; i < 12; i++)
46 | {
47 | var position = Vector3.Transform(
48 | new Vector3(0, 0.5f + e, 6.5f), orientation);
49 |
50 | var body = new RigidBody(shape)
51 | {
52 | Orientation = Conversion.ToJitterMatrix(orientation),
53 | Position = Conversion.ToJitterVector(position)
54 | };
55 |
56 | world.AddBody(body);
57 |
58 | orientation *= fullRotationStep;
59 | }
60 | }
61 |
62 | //for (int e = 0; e < 40; e++)
63 | //{
64 | // orientation *= halfRotationStep;
65 |
66 | // for (int i = 0; i < 12; i++)
67 | // {
68 | // Vector3 position = Vector3.Transform(
69 | // new Vector3(0, 0.5f + e, 6.5f), orientation);
70 |
71 | // RigidBody body = new RigidBody(shape);
72 | // body.Orientation = Conversion.ToJitterMatrix(orientation);
73 | // body.Position = Conversion.ToJitterVector(position) + new JVector(20,0,0);
74 |
75 | // world.AddBody(body);
76 |
77 | // orientation *= fullRotationStep;
78 | // }
79 | //}
80 |
81 | //for (int e = 0; e < 40; e++)
82 | //{
83 | // orientation *= halfRotationStep;
84 |
85 | // for (int i = 0; i < 12; i++)
86 | // {
87 | // Vector3 position = Vector3.Transform(
88 | // new Vector3(0, 0.5f + e, 6.5f), orientation);
89 |
90 | // RigidBody body = new RigidBody(shape);
91 | // body.Orientation = Conversion.ToJitterMatrix(orientation);
92 | // body.Position = Conversion.ToJitterVector(position) + new JVector(00, 0, -20); ;
93 |
94 | // world.AddBody(body);
95 |
96 | // orientation *= fullRotationStep;
97 | // }
98 | //}
99 |
100 | //for (int e = 0; e < 40; e++)
101 | //{
102 | // orientation *= halfRotationStep;
103 |
104 | // for (int i = 0; i < 12; i++)
105 | // {
106 | // Vector3 position = Vector3.Transform(
107 | // new Vector3(0, 0.5f + e, 6.5f), orientation);
108 |
109 | // RigidBody body = new RigidBody(shape);
110 | // body.Orientation = Conversion.ToJitterMatrix(orientation);
111 | // body.Position = Conversion.ToJitterVector(position) + new JVector(20, 0, -20);
112 |
113 | // world.AddBody(body);
114 |
115 | // orientation *= fullRotationStep;
116 | // }
117 | //}
118 |
119 | //for (int i = 0; i < 15; i++)
120 | //{
121 | // for (int k = 0; k < 15; k++)
122 | // {
123 | // for (int l = 0; l < 15; l++)
124 | // {
125 | // RigidBody body = new RigidBody(new BoxShape(1, 1, 1));
126 | // this.Demo.World.AddBody(body);
127 | // body.AffectedByGravity = false;
128 | // body.Position = new JVector(i, k, l) * 2.0f;
129 | // body.Restitution = 1.0f;
130 | // body.Damping = RigidBody.DampingType.None;
131 | // body.IsActive = false;
132 | // }
133 | // }
134 | //}
135 |
136 | ground.Material.StaticFriction = 1.0f;
137 | ground.Material.KineticFriction = 1.0f;
138 | }
139 | }
140 | }
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Scenes/TriangleMesh.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Microsoft.Xna.Framework.Graphics;
4 | using Microsoft.Xna.Framework;
5 | using Jitter.LinearMath;
6 | using Jitter.Collision.Shapes;
7 | using Jitter.Dynamics;
8 | using Jitter.Collision;
9 |
10 | namespace JitterDemo.Scenes
11 | {
12 | public class TriangleMesh : Scene
13 | {
14 | private Model model;
15 |
16 | public TriangleMesh(JitterDemo demo)
17 | : base(demo)
18 | {
19 | }
20 |
21 | ///
22 | /// Helper Method to get the vertex and index List from the model.
23 | ///
24 | ///
25 | ///
26 | ///
27 | public void ExtractData(List vertices, List indices, Model model)
28 | {
29 | var bones_ = new Matrix[model.Bones.Count];
30 | model.CopyAbsoluteBoneTransformsTo(bones_);
31 | foreach (var mm in model.Meshes)
32 | {
33 | var xform = bones_[mm.ParentBone.Index];
34 | foreach (var mmp in mm.MeshParts)
35 | {
36 | int offset = vertices.Count;
37 | var a = new Vector3[mmp.NumVertices];
38 | mmp.VertexBuffer.GetData(mmp.VertexOffset * mmp.VertexBuffer.VertexDeclaration.VertexStride,
39 | a, 0, mmp.NumVertices, mmp.VertexBuffer.VertexDeclaration.VertexStride);
40 | for (int i = 0; i != a.Length; ++i)
41 | Vector3.Transform(ref a[i], ref xform, out a[i]);
42 | vertices.AddRange(a);
43 |
44 | if (mmp.IndexBuffer.IndexElementSize != IndexElementSize.SixteenBits)
45 | throw new Exception(
46 | String.Format("Model uses 32-bit indices, which are not supported."));
47 | short[] s = new short[mmp.PrimitiveCount * 3];
48 | mmp.IndexBuffer.GetData(mmp.StartIndex * 2, s, 0, mmp.PrimitiveCount * 3);
49 | var tvi = new TriangleVertexIndices[mmp.PrimitiveCount];
50 | for (int i = 0; i != tvi.Length; ++i)
51 | {
52 | tvi[i].I0 = s[(i * 3) + 0] + offset;
53 | tvi[i].I1 = s[(i * 3) + 1] + offset;
54 | tvi[i].I2 = s[(i * 3) + 2] + offset;
55 | }
56 | indices.AddRange(tvi);
57 | }
58 | }
59 | }
60 |
61 | public override void Draw()
62 | {
63 | var camera = Demo.Camera;
64 |
65 | foreach (var mesh in model.Meshes)
66 | {
67 | foreach (BasicEffect effect in mesh.Effects)
68 | {
69 | effect.World = boneTransforms[mesh.ParentBone.Index];
70 | effect.View = camera.View;
71 | effect.Projection = camera.Projection;
72 |
73 | effect.EnableDefaultLighting();
74 | effect.PreferPerPixelLighting = true;
75 | }
76 | mesh.Draw();
77 | }
78 | }
79 |
80 | private Matrix[] boneTransforms;
81 |
82 | public override void Build()
83 | {
84 | model = Demo.Content.Load("staticmesh");
85 | boneTransforms = new Matrix[model.Bones.Count];
86 | model.CopyAbsoluteBoneTransformsTo(boneTransforms);
87 |
88 | var indices = new List();
89 | var vertices = new List();
90 |
91 | ExtractData(vertices, indices, model);
92 |
93 | var jvertices = new List(vertices.Count);
94 | foreach(var vertex in vertices) jvertices.Add(Conversion.ToJitterVector(vertex));
95 |
96 | var octree = new Octree(jvertices, indices);
97 |
98 | var tms = new TriangleMeshShape(octree);
99 | var body = new RigidBody(tms)
100 | {
101 | IsStatic = true,
102 | //body.EnableDebugDraw = true;
103 | Tag = BodyTag.DontDrawMe
104 | };
105 |
106 | Demo.World.AddBody(body);
107 |
108 | AddCar(new JVector(-20, 20, 0));
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/Scenes/Wall.cs:
--------------------------------------------------------------------------------
1 | using Jitter.Collision.Shapes;
2 | using Jitter.Dynamics;
3 | using Jitter.LinearMath;
4 |
5 | namespace JitterDemo.Scenes
6 | {
7 | internal class Wall : Scene
8 | {
9 | public Wall(JitterDemo demo)
10 | : base(demo)
11 | {
12 | }
13 |
14 | public override void Build()
15 | {
16 | AddGround();
17 |
18 | for (int k = 0; k < 1; k++)
19 | {
20 | for (int i = 0; i < 20; i++)
21 | {
22 | for (int e = 0; e < 20; e++)
23 | {
24 | var body = new RigidBody(new BoxShape(2, 1, 1))
25 | {
26 | Position = new JVector((e * 2.01f) + ((i % 2 == 0) ? 1f : 0.0f), 0.5f + (i * 1.0f), k * 5)
27 | };
28 | Demo.World.AddBody(body);
29 | }
30 | }
31 | }
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/samples/JitterDemo/JitterDemo/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/source/Jitter.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.24720.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jitter", "Jitter\Jitter.csproj", "{AA03EF1A-94F7-4D30-AB14-2092863FF923}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jitter.Portable", "Jitter\Jitter.Portable.csproj", "{AA03EF1A-94F7-4D30-AB14-2092863FF92A}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {AA03EF1A-94F7-4D30-AB14-2092863FF923}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {AA03EF1A-94F7-4D30-AB14-2092863FF923}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {AA03EF1A-94F7-4D30-AB14-2092863FF923}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {AA03EF1A-94F7-4D30-AB14-2092863FF923}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {AA03EF1A-94F7-4D30-AB14-2092863FF92A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {AA03EF1A-94F7-4D30-AB14-2092863FF92A}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {AA03EF1A-94F7-4D30-AB14-2092863FF92A}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {AA03EF1A-94F7-4D30-AB14-2092863FF92A}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | EndGlobal
29 |
--------------------------------------------------------------------------------
/source/Jitter/ArrayResourcePool.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Jitter
4 | {
5 | public class ArrayResourcePool
6 | {
7 | private readonly Stack stack = new Stack();
8 |
9 | private readonly int arrayLength;
10 |
11 | public ArrayResourcePool(int arrayLength)
12 | {
13 | this.arrayLength = arrayLength;
14 | }
15 |
16 | public void ResetResourcePool()
17 | {
18 | lock (stack) { stack.Clear(); }
19 | }
20 |
21 | public int Count => stack.Count;
22 |
23 | public void GiveBack(T[] obj)
24 | {
25 | lock (stack) { stack.Push(obj); }
26 | }
27 |
28 | public T[] GetNew()
29 | {
30 | T[] freeObj;
31 |
32 | lock (stack)
33 | {
34 | if (stack.Count == 0)
35 | {
36 | freeObj = new T[arrayLength];
37 | stack.Push(freeObj);
38 | }
39 |
40 | freeObj = stack.Pop();
41 | }
42 |
43 | return freeObj;
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/source/Jitter/Collision/CollisionIsland.cs:
--------------------------------------------------------------------------------
1 | using Jitter.DataStructures;
2 | using Jitter.Dynamics;
3 | using Jitter.Dynamics.Constraints;
4 | using System.Collections.Generic;
5 |
6 | namespace Jitter.Collision
7 | {
8 | public class CollisionIsland
9 | {
10 | internal IslandManager islandManager;
11 | internal HashSet bodies = new HashSet();
12 | internal HashSet arbiter = new HashSet();
13 | internal HashSet constraints = new HashSet();
14 |
15 | public ReadOnlyHashset Bodies { get; }
16 | public ReadOnlyHashset Arbiter { get; }
17 | public ReadOnlyHashset Constraints { get; }
18 |
19 | public CollisionIsland()
20 | {
21 | Bodies = new ReadOnlyHashset(bodies);
22 | Arbiter = new ReadOnlyHashset(arbiter);
23 | Constraints = new ReadOnlyHashset(constraints);
24 | }
25 |
26 | public bool IsActive()
27 | {
28 | var enumerator = bodies.GetEnumerator();
29 | enumerator.MoveNext();
30 |
31 | return enumerator.Current?.isActive == true;
32 | }
33 |
34 | public void SetStatus(bool active)
35 | {
36 | foreach (var body in bodies)
37 | {
38 | body.IsActive = active;
39 | if (active && !body.IsActive)
40 | {
41 | body.inactiveTime = 0.0f;
42 | }
43 | }
44 | }
45 |
46 | internal void ClearLists()
47 | {
48 | arbiter.Clear();
49 | bodies.Clear();
50 | constraints.Clear();
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/source/Jitter/Collision/DynamicTreeNode.cs:
--------------------------------------------------------------------------------
1 | using Jitter.LinearMath;
2 |
3 | namespace Jitter.Collision
4 | {
5 | public struct DynamicTreeNode
6 | {
7 | public JBBox AABB;
8 |
9 | public float MinorRandomExtension;
10 |
11 | public int Child1;
12 | public int Child2;
13 |
14 | public int LeafCount;
15 | public int ParentOrNext;
16 | public T UserData;
17 |
18 | public bool IsLeaf()
19 | {
20 | return Child1 == DynamicTree.NullNode;
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/source/Jitter/Collision/IBroadphaseEntity.cs:
--------------------------------------------------------------------------------
1 | using Jitter.LinearMath;
2 |
3 | namespace Jitter.Collision
4 | {
5 | public interface IBroadphaseEntity
6 | {
7 | JBBox BoundingBox { get; }
8 | bool IsStaticOrInactive { get; }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/source/Jitter/Collision/Shapes/BoxShape.cs:
--------------------------------------------------------------------------------
1 | using Jitter.LinearMath;
2 | using System;
3 |
4 | namespace Jitter.Collision.Shapes
5 | {
6 | public class BoxShape : Shape
7 | {
8 | private JVector size = JVector.Zero;
9 | private JVector halfSize = JVector.Zero;
10 |
11 | public JVector Size
12 | {
13 | get => size;
14 | set
15 | {
16 | size = value;
17 | UpdateShape();
18 | }
19 | }
20 |
21 | public BoxShape(JVector size)
22 | {
23 | this.size = size;
24 | UpdateShape();
25 | }
26 |
27 | public BoxShape(float length, float height, float width)
28 | {
29 | size = new JVector(
30 | length,
31 | height,
32 | width);
33 | UpdateShape();
34 | }
35 |
36 | public override void UpdateShape()
37 | {
38 | halfSize = size * 0.5f;
39 | base.UpdateShape();
40 | }
41 |
42 | public override void GetBoundingBox(in JMatrix orientation, out JBBox box)
43 | {
44 | JMath.Absolute(orientation, out var abs);
45 | var max = JVector.Transform(halfSize, abs);
46 |
47 | box = new JBBox(
48 | JVector.Negate(max),
49 | max);
50 | }
51 |
52 | public override void CalculateMassInertia()
53 | {
54 | mass = size.X * size.Y * size.Z;
55 |
56 | inertia = JMatrix.FromDiagonal(
57 | m11: 1.0f / 12.0f * mass * ((size.Y * size.Y) + (size.Z * size.Z)),
58 | m22: 1.0f / 12.0f * mass * ((size.X * size.X) + (size.Z * size.Z)),
59 | m33: 1.0f / 12.0f * mass * ((size.X * size.X) + (size.Y * size.Y)));
60 |
61 | geomCen = JVector.Zero;
62 | }
63 |
64 | public override void SupportMapping(in JVector direction, out JVector result)
65 | {
66 | result = new JVector(
67 | Math.Sign(direction.X) * halfSize.X,
68 | Math.Sign(direction.Y) * halfSize.Y,
69 | Math.Sign(direction.Z) * halfSize.Z);
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/source/Jitter/Collision/Shapes/CapsuleShape.cs:
--------------------------------------------------------------------------------
1 | using Jitter.LinearMath;
2 | using System;
3 |
4 | namespace Jitter.Collision.Shapes
5 | {
6 | public class CapsuleShape : Shape
7 | {
8 | private float length;
9 | private float radius;
10 |
11 | public float Length
12 | {
13 | get => length;
14 | set
15 | {
16 | length = value;
17 | UpdateShape();
18 | }
19 | }
20 |
21 | public float Radius
22 | {
23 | get => radius;
24 | set
25 | {
26 | radius = value;
27 | UpdateShape();
28 | }
29 | }
30 |
31 | public CapsuleShape(float length, float radius)
32 | {
33 | this.length = length;
34 | this.radius = radius;
35 | UpdateShape();
36 | }
37 |
38 | public override void CalculateMassInertia()
39 | {
40 | float massSphere = 3.0f / 4.0f * JMath.Pi * radius * radius * radius;
41 | float massCylinder = JMath.Pi * radius * radius * length;
42 |
43 | mass = massCylinder + massSphere;
44 |
45 | inertia = JMatrix.FromDiagonal(
46 | m11: (1.0f / 4.0f * massCylinder * radius * radius) + (1.0f / 12.0f * massCylinder * length * length) + (2.0f / 5.0f * massSphere * radius * radius) + (1.0f / 4.0f * length * length * massSphere),
47 | m22: (1.0f / 2.0f * massCylinder * radius * radius) + (2.0f / 5.0f * massSphere * radius * radius),
48 | m33: (1.0f / 4.0f * massCylinder * radius * radius) + (1.0f / 12.0f * massCylinder * length * length) + (2.0f / 5.0f * massSphere * radius * radius) + (1.0f / 4.0f * length * length * massSphere));
49 | }
50 |
51 | public override void SupportMapping(in JVector direction, out JVector result)
52 | {
53 | float r = JMath.Sqrt((direction.X * direction.X) + (direction.Z * direction.Z));
54 |
55 | if (Math.Abs(direction.Y) > 0.0f)
56 | {
57 | JVector.Normalize(in direction, out var dir);
58 | JVector.Multiply(in dir, radius, out result);
59 |
60 | result = new JVector(
61 | result.X,
62 | result.Y + Math.Sign(direction.Y) * 0.5f * length,
63 | result.Z);
64 | }
65 | else if (r > 0.0f)
66 | {
67 | result = new JVector(
68 | direction.X / r * radius,
69 | 0.0f,
70 | direction.Z / r * radius);
71 | }
72 | else
73 | {
74 | result = new JVector();
75 | }
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/source/Jitter/Collision/Shapes/ConeShape.cs:
--------------------------------------------------------------------------------
1 | using Jitter.LinearMath;
2 | using System;
3 |
4 | namespace Jitter.Collision.Shapes
5 | {
6 | public class ConeShape : Shape
7 | {
8 | private float height;
9 | private float radius;
10 | private float sina;
11 |
12 | public float Height
13 | {
14 | get => height;
15 | set
16 | {
17 | height = value;
18 | UpdateShape();
19 | }
20 | }
21 |
22 | public float Radius
23 | {
24 | get => radius;
25 | set
26 | {
27 | radius = value;
28 | UpdateShape();
29 | }
30 | }
31 |
32 | public ConeShape(float height, float radius)
33 | {
34 | this.height = height;
35 | this.radius = radius;
36 |
37 | UpdateShape();
38 | }
39 |
40 | public override void UpdateShape()
41 | {
42 | sina = radius / JMath.Sqrt((radius * radius) + (height * height));
43 | base.UpdateShape();
44 | }
45 |
46 | public override void CalculateMassInertia()
47 | {
48 | mass = 1.0f / 3.0f * JMath.Pi * radius * radius * height;
49 |
50 | inertia = JMatrix.FromDiagonal(
51 | m11: 3.0f / 80.0f * mass * ((radius * radius) + (4 * height * height)),
52 | m22: 3.0f / 10.0f * mass * radius * radius,
53 | m33: 3.0f / 80.0f * mass * ((radius * radius) + (4 * height * height)));
54 |
55 | geomCen = JVector.Zero;
56 | }
57 |
58 | public override void SupportMapping(in JVector direction, out JVector result)
59 | {
60 | float sigma = JMath.Sqrt((direction.X * direction.X) + (direction.Z * direction.Z));
61 |
62 | if (direction.Y > direction.Length() * sina)
63 | {
64 | result = new JVector(
65 | 0.0f,
66 | 2.0f / 3.0f * height,
67 | 0.0f);
68 | }
69 | else if (sigma > 0.0f)
70 | {
71 | result = new JVector(
72 | radius * direction.X / sigma,
73 | -(1.0f / 3.0f) * height,
74 | radius * direction.Z / sigma);
75 | }
76 | else
77 | {
78 | result = new JVector(
79 | 0.0f,
80 | -(1.0f / 3.0f) * height,
81 | 0.0f);
82 | }
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/source/Jitter/Collision/Shapes/ConvexHullShape.cs:
--------------------------------------------------------------------------------
1 | using Jitter.LinearMath;
2 | using System.Collections.Generic;
3 |
4 | namespace Jitter.Collision.Shapes
5 | {
6 | public class ConvexHullShape : Shape
7 | {
8 | private readonly List vertices;
9 | private JVector shifted;
10 |
11 | public ConvexHullShape(List vertices)
12 | {
13 | this.vertices = vertices;
14 | UpdateShape();
15 | }
16 |
17 | public JVector Shift => -1 * shifted;
18 |
19 | public override void CalculateMassInertia()
20 | {
21 | mass = CalculateMassInertia(this, out shifted, out inertia);
22 | }
23 |
24 | public override void SupportMapping(in JVector direction, out JVector result)
25 | {
26 | float maxDotProduct = float.MinValue;
27 | int maxIndex = 0;
28 | float dotProduct;
29 |
30 | for (int i = 0; i < vertices.Count; i++)
31 | {
32 | dotProduct = JVector.Dot(vertices[i], direction);
33 | if (dotProduct > maxDotProduct)
34 | {
35 | maxDotProduct = dotProduct;
36 | maxIndex = i;
37 | }
38 | }
39 |
40 | result = vertices[maxIndex] - shifted;
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/source/Jitter/Collision/Shapes/CylinderShape.cs:
--------------------------------------------------------------------------------
1 | using Jitter.LinearMath;
2 | using System;
3 |
4 | namespace Jitter.Collision.Shapes
5 | {
6 | public class CylinderShape : Shape
7 | {
8 | private float height;
9 | private float radius;
10 |
11 | public float Height
12 | {
13 | get => height; set
14 | {
15 | height = value;
16 | UpdateShape();
17 | }
18 | }
19 |
20 | public float Radius
21 | {
22 | get => radius; set
23 | {
24 | radius = value;
25 | UpdateShape();
26 | }
27 | }
28 |
29 | public CylinderShape(float height, float radius)
30 | {
31 | this.height = height;
32 | this.radius = radius;
33 | UpdateShape();
34 | }
35 |
36 | public override void CalculateMassInertia()
37 | {
38 | mass = JMath.Pi * radius * radius * height;
39 |
40 | inertia = JMatrix.FromDiagonal(
41 | m11: (1.0f / 4.0f * mass * radius * radius) + (1.0f / 12.0f * mass * height * height),
42 | m22: 1.0f / 2.0f * mass * radius * radius,
43 | m33: (1.0f / 4.0f * mass * radius * radius) + (1.0f / 12.0f * mass * height * height));
44 | }
45 |
46 | public override void SupportMapping(in JVector direction, out JVector result)
47 | {
48 | float sigma = JMath.Sqrt((direction.X * direction.X) + (direction.Z * direction.Z));
49 |
50 | if (sigma > 0.0f)
51 | {
52 | result = new JVector(
53 | direction.X / sigma * radius,
54 | Math.Sign(direction.Y) * height * 0.5f,
55 | direction.Z / sigma * radius);
56 | }
57 | else
58 | {
59 | result = new JVector(
60 | 0.0f,
61 | Math.Sign(direction.Y) * height * 0.5f,
62 | 0.0f);
63 | }
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/source/Jitter/Collision/Shapes/MinkowskiSumShape.cs:
--------------------------------------------------------------------------------
1 | using Jitter.LinearMath;
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | namespace Jitter.Collision.Shapes
6 | {
7 | public class MinkowskiSumShape : Shape
8 | {
9 | private JVector shifted;
10 | private readonly List shapes = new List();
11 |
12 | public MinkowskiSumShape(IEnumerable shapes)
13 | {
14 | AddShapes(shapes);
15 | }
16 |
17 | public void AddShapes(IEnumerable shapes)
18 | {
19 | foreach (var shape in shapes)
20 | {
21 | if (shape is Multishape)
22 | {
23 | throw new Exception("Multishapes not supported by MinkowskiSumShape.");
24 | }
25 |
26 | this.shapes.Add(shape);
27 | }
28 |
29 | UpdateShape();
30 | }
31 |
32 | public void AddShape(Shape shape)
33 | {
34 | if (shape is Multishape)
35 | {
36 | throw new Exception("Multishapes not supported by MinkowskiSumShape.");
37 | }
38 |
39 | shapes.Add(shape);
40 |
41 | UpdateShape();
42 | }
43 |
44 | public bool Remove(Shape shape)
45 | {
46 | if (shapes.Count == 1)
47 | {
48 | throw new Exception("There must be at least one shape.");
49 | }
50 |
51 | bool result = shapes.Remove(shape);
52 | UpdateShape();
53 | return result;
54 | }
55 |
56 | public JVector Shift()
57 | {
58 | return -1 * shifted;
59 | }
60 |
61 | public override void CalculateMassInertia()
62 | {
63 | mass = CalculateMassInertia(this, out shifted, out inertia);
64 | }
65 |
66 | public override void SupportMapping(in JVector direction, out JVector result)
67 | {
68 | var temp2 = JVector.Zero;
69 |
70 | for (int i = 0; i < shapes.Count; i++)
71 | {
72 | shapes[i].SupportMapping(in direction, out var temp1);
73 | JVector.Add( temp1, temp2, out temp2);
74 | }
75 |
76 | JVector.Subtract(temp2, shifted, out result);
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/source/Jitter/Collision/Shapes/Multishape.cs:
--------------------------------------------------------------------------------
1 | using Jitter.LinearMath;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 |
5 | namespace Jitter.Collision.Shapes
6 | {
7 | public abstract class Multishape : Shape
8 | {
9 | public abstract void SetCurrentShape(int index);
10 |
11 | public abstract int Prepare(in JBBox box);
12 |
13 | public abstract int Prepare(in JVector rayOrigin, in JVector rayDelta);
14 |
15 | protected abstract Multishape CreateWorkingClone();
16 |
17 | internal bool isClone;
18 |
19 | public bool IsClone => isClone;
20 |
21 | private Stack workingCloneStack = new Stack();
22 |
23 | public Multishape RequestWorkingClone()
24 | {
25 | Debug.Assert(workingCloneStack.Count < 10, "Unusual size of the workingCloneStack. Forgot to call ReturnWorkingClone?");
26 | Debug.Assert(!isClone, "Can't clone clones! Something wrong here!");
27 |
28 | Multishape multiShape;
29 |
30 | lock (workingCloneStack)
31 | {
32 | if (workingCloneStack.Count == 0)
33 | {
34 | multiShape = CreateWorkingClone();
35 | multiShape.workingCloneStack = workingCloneStack;
36 | workingCloneStack.Push(multiShape);
37 | }
38 | multiShape = workingCloneStack.Pop();
39 | multiShape.isClone = true;
40 | }
41 |
42 | return multiShape;
43 | }
44 |
45 | public override void UpdateShape()
46 | {
47 | lock (workingCloneStack)
48 | {
49 | workingCloneStack.Clear();
50 | }
51 |
52 | base.UpdateShape();
53 | }
54 |
55 | public void ReturnWorkingClone()
56 | {
57 | Debug.Assert(isClone, "Only clones can be returned!");
58 | lock (workingCloneStack) { workingCloneStack.Push(this); }
59 | }
60 |
61 | public override void GetBoundingBox(in JMatrix orientation, out JBBox box)
62 | {
63 | var helpBox = JBBox.LargeBox;
64 | int length = Prepare(helpBox);
65 |
66 | box = JBBox.SmallBox;
67 |
68 | for (int i = 0; i < length; i++)
69 | {
70 | SetCurrentShape(i);
71 | base.GetBoundingBox(orientation, out helpBox);
72 | JBBox.CreateMerged(box, helpBox, out box);
73 | }
74 | }
75 |
76 | public override void MakeHull(List triangleList, int generationThreshold)
77 | {
78 | }
79 |
80 | public override void CalculateMassInertia()
81 | {
82 | geomCen = JVector.Zero;
83 |
84 | inertia = JMatrix.Identity;
85 |
86 | JVector.Subtract(boundingBox.Max, boundingBox.Min, out var size);
87 |
88 | mass = size.X * size.Y * size.Z;
89 |
90 | inertia = JMatrix.FromDiagonal(
91 | m11: 1.0f / 12.0f * mass * ((size.Y * size.Y) + (size.Z * size.Z)),
92 | m22: 1.0f / 12.0f * mass * ((size.X * size.X) + (size.Z * size.Z)),
93 | m33: 1.0f / 12.0f * mass * ((size.X * size.X) + (size.Y * size.Y)));
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/source/Jitter/Collision/Shapes/SphereShape.cs:
--------------------------------------------------------------------------------
1 | using Jitter.LinearMath;
2 |
3 | namespace Jitter.Collision.Shapes
4 | {
5 | public class SphereShape : Shape
6 | {
7 | private float radius = 1.0f;
8 |
9 | public float Radius
10 | {
11 | get => radius; set
12 | {
13 | radius = value;
14 | UpdateShape();
15 | }
16 | }
17 |
18 | public SphereShape(float radius)
19 | {
20 | this.radius = radius;
21 | UpdateShape();
22 | }
23 |
24 | public override void SupportMapping(in JVector direction, out JVector result)
25 | {
26 | result = direction;
27 | result = JVector.Normalize(result);
28 |
29 | JVector.Multiply(result, radius, out result);
30 | }
31 |
32 | public override void GetBoundingBox(in JMatrix orientation, out JBBox box)
33 | {
34 | box = new JBBox(
35 | new JVector(-radius, -radius, -radius),
36 | new JVector(radius, radius, radius));
37 | }
38 |
39 | public override void CalculateMassInertia()
40 | {
41 | mass = 4.0f / 3.0f * JMath.Pi * radius * radius * radius;
42 |
43 | inertia = JMatrix.FromDiagonal(
44 | m11: 0.4f * mass * radius * radius,
45 | m22: 0.4f * mass * radius * radius,
46 | m33: 0.4f * mass * radius * radius);
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/source/Jitter/Collision/Shapes/TriangleMeshShape.cs:
--------------------------------------------------------------------------------
1 | using Jitter.LinearMath;
2 | using System.Collections.Generic;
3 |
4 | namespace Jitter.Collision.Shapes
5 | {
6 | public class TriangleMeshShape : Multishape
7 | {
8 | private readonly List potentialTriangles = new List();
9 | private readonly Octree octree;
10 |
11 | public float SphericalExpansion { get; set; } = 0.05f;
12 |
13 | public TriangleMeshShape(Octree octree)
14 | {
15 | this.octree = octree;
16 | UpdateShape();
17 | }
18 |
19 | internal TriangleMeshShape() { }
20 |
21 | protected override Multishape CreateWorkingClone()
22 | {
23 | var clone = new TriangleMeshShape(octree)
24 | {
25 | SphericalExpansion = SphericalExpansion
26 | };
27 | return clone;
28 | }
29 |
30 | public override int Prepare(in JBBox box)
31 | {
32 | potentialTriangles.Clear();
33 |
34 | var exp = new JBBox(
35 | new JVector(box.Min.X - SphericalExpansion, box.Min.Y - SphericalExpansion, box.Min.Z - SphericalExpansion),
36 | new JVector(box.Max.X + SphericalExpansion, box.Max.Y + SphericalExpansion, box.Max.Z + SphericalExpansion));
37 |
38 | octree.GetTrianglesIntersectingtAABox(potentialTriangles, exp);
39 |
40 | return potentialTriangles.Count;
41 | }
42 |
43 | public override void MakeHull(List triangleList, int generationThreshold)
44 | {
45 | var large = JBBox.LargeBox;
46 |
47 | var indices = new List();
48 | octree.GetTrianglesIntersectingtAABox(indices, large);
49 |
50 | for (int i = 0; i < indices.Count; i++)
51 | {
52 | triangleList.Add(octree.GetVertex(octree.GetTriangleVertexIndex(i).I0));
53 | triangleList.Add(octree.GetVertex(octree.GetTriangleVertexIndex(i).I1));
54 | triangleList.Add(octree.GetVertex(octree.GetTriangleVertexIndex(i).I2));
55 | }
56 | }
57 |
58 | public override int Prepare(in JVector rayOrigin, in JVector rayDelta)
59 | {
60 | potentialTriangles.Clear();
61 |
62 | JVector.Normalize(rayDelta, out var expDelta);
63 | expDelta = rayDelta + (expDelta * SphericalExpansion);
64 |
65 | octree.GetTrianglesIntersectingRay(potentialTriangles, rayOrigin, expDelta);
66 |
67 | return potentialTriangles.Count;
68 | }
69 |
70 | private readonly JVector[] vecs = new JVector[3];
71 |
72 | public override void SupportMapping(in JVector direction, out JVector result)
73 | {
74 | JVector.Normalize(direction, out var exp);
75 | exp *= SphericalExpansion;
76 |
77 | float min = JVector.Dot(vecs[0], direction);
78 | int minIndex = 0;
79 | float dot = JVector.Dot(vecs[1], direction);
80 | if (dot > min)
81 | {
82 | min = dot;
83 | minIndex = 1;
84 | }
85 | dot = JVector.Dot(vecs[2], direction);
86 | if (dot > min)
87 | {
88 | minIndex = 2;
89 | }
90 |
91 | result = vecs[minIndex] + exp;
92 | }
93 |
94 | public override void GetBoundingBox(in JMatrix orientation, out JBBox box)
95 | {
96 | box = octree.rootNodeBox;
97 |
98 | box = new JBBox(
99 | new JVector(box.Min.X - SphericalExpansion, box.Min.Y - SphericalExpansion, box.Min.Z - SphericalExpansion),
100 | new JVector(box.Max.X + SphericalExpansion, box.Max.Y + SphericalExpansion, box.Max.Z + SphericalExpansion));
101 |
102 | box = box.Transform(orientation);
103 | }
104 |
105 | public bool FlipNormals { get; set; }
106 |
107 | public override void SetCurrentShape(int index)
108 | {
109 | vecs[0] = octree.GetVertex(octree.tris[potentialTriangles[index]].I0);
110 | vecs[1] = octree.GetVertex(octree.tris[potentialTriangles[index]].I1);
111 | vecs[2] = octree.GetVertex(octree.tris[potentialTriangles[index]].I2);
112 |
113 | var sum = vecs[0];
114 | JVector.Add(sum, vecs[1], out sum);
115 | JVector.Add(sum, vecs[2], out sum);
116 | JVector.Multiply(sum, 1.0f / 3.0f, out sum);
117 |
118 | geomCen = sum;
119 |
120 | JVector.Subtract(vecs[1], vecs[0], out sum);
121 | JVector.Subtract(vecs[2], vecs[0], out normal);
122 | JVector.Cross(sum, normal, out normal);
123 |
124 | if (FlipNormals)
125 | {
126 | normal = JVector.Negate(normal);
127 | }
128 | }
129 |
130 | private JVector normal = JVector.Up;
131 |
132 | public void CollisionNormal(out JVector normal)
133 | {
134 | normal = this.normal;
135 | }
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/source/Jitter/Collision/TriangleVertexIndices.cs:
--------------------------------------------------------------------------------
1 | using Jitter.LinearMath;
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | namespace Jitter.Collision
6 | {
7 | public struct TriangleVertexIndices
8 | {
9 | public int I0;
10 | public int I1;
11 | public int I2;
12 |
13 | public TriangleVertexIndices(int i0, int i1, int i2)
14 | {
15 | I0 = i0;
16 | I1 = i1;
17 | I2 = i2;
18 | }
19 |
20 | public void Set(int i0, int i1, int i2)
21 | {
22 | I0 = i0; I1 = i1; I2 = i2;
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/source/Jitter/DataStructures/ReadOnlyHashset.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 |
4 | namespace Jitter.DataStructures
5 | {
6 | public class ReadOnlyHashset : IEnumerable, IEnumerable
7 | {
8 | private readonly HashSet hashset;
9 |
10 | public ReadOnlyHashset(HashSet hashset) { this.hashset = hashset; }
11 |
12 | public IEnumerator GetEnumerator()
13 | {
14 | return hashset.GetEnumerator();
15 | }
16 |
17 | IEnumerator IEnumerable.GetEnumerator()
18 | {
19 | return hashset.GetEnumerator();
20 | }
21 |
22 | public int Count => hashset.Count;
23 |
24 | public bool Contains(T item) { return hashset.Contains(item); }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/source/Jitter/Dynamics/ArbiterKey.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 |
4 | namespace Jitter.Dynamics
5 | {
6 | public struct ArbiterKey
7 | {
8 | internal RigidBody body1, body2;
9 |
10 | public ArbiterKey(RigidBody body1, RigidBody body2)
11 | {
12 | this.body1 = body1;
13 | this.body2 = body2;
14 | }
15 |
16 | internal void SetBodies(RigidBody body1, RigidBody body2)
17 | {
18 | this.body1 = body1;
19 | this.body2 = body2;
20 | }
21 |
22 | public override bool Equals(object obj)
23 | {
24 | var other = (ArbiterKey)obj;
25 | return (other.body1.Equals(body1) && other.body2.Equals(body2))
26 | || (other.body1.Equals(body2) && other.body2.Equals(body1));
27 | }
28 |
29 | public override int GetHashCode()
30 | {
31 | return body1.GetHashCode() + body2.GetHashCode();
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/source/Jitter/Dynamics/ArbiterKeyComparer.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 |
4 | namespace Jitter.Dynamics
5 | {
6 |
7 | internal class ArbiterKeyComparer : IEqualityComparer
8 | {
9 | public bool Equals(ArbiterKey x, ArbiterKey y)
10 | {
11 | return (x.body1.Equals(y.body1) && x.body2.Equals(y.body2))
12 | || (x.body1.Equals(y.body2) && x.body2.Equals(y.body1));
13 | }
14 |
15 | public int GetHashCode(ArbiterKey obj)
16 | {
17 | return obj.body1.GetHashCode() + obj.body2.GetHashCode();
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/source/Jitter/Dynamics/ArbiterMap.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 |
4 | namespace Jitter.Dynamics
5 | {
6 | public class ArbiterMap : IEnumerable
7 | {
8 | private readonly Dictionary dictionary =
9 | new Dictionary(2048, arbiterKeyComparer);
10 |
11 | private ArbiterKey lookUpKey;
12 | private static readonly ArbiterKeyComparer arbiterKeyComparer = new ArbiterKeyComparer();
13 |
14 | public ArbiterMap()
15 | {
16 | lookUpKey = new ArbiterKey(null, null);
17 | }
18 |
19 | public bool LookUpArbiter(RigidBody body1, RigidBody body2, out Arbiter arbiter)
20 | {
21 | lookUpKey.SetBodies(body1, body2);
22 | return dictionary.TryGetValue(lookUpKey, out arbiter);
23 | }
24 |
25 | public Dictionary.ValueCollection Arbiters => dictionary.Values;
26 |
27 | internal void Add(ArbiterKey key, Arbiter arbiter)
28 | {
29 | dictionary.Add(key, arbiter);
30 | }
31 |
32 | internal void Clear()
33 | {
34 | dictionary.Clear();
35 | }
36 |
37 | internal void Remove(Arbiter arbiter)
38 | {
39 | lookUpKey.SetBodies(arbiter.body1, arbiter.body2);
40 | dictionary.Remove(lookUpKey);
41 | }
42 |
43 | public bool ContainsArbiter(RigidBody body1, RigidBody body2)
44 | {
45 | lookUpKey.SetBodies(body1, body2);
46 | return dictionary.ContainsKey(lookUpKey);
47 | }
48 |
49 | public IEnumerator GetEnumerator()
50 | {
51 | return dictionary.Values.GetEnumerator();
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/source/Jitter/Dynamics/Constraint.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 |
4 | namespace Jitter.Dynamics.Constraints
5 | {
6 | public abstract class Constraint : IConstraint, IDebugDrawable, IComparable
7 | {
8 | internal RigidBody body1;
9 | internal RigidBody body2;
10 |
11 | public RigidBody Body1 => body1;
12 |
13 | public RigidBody Body2 => body2;
14 |
15 | private static int instanceCount;
16 | private readonly int instance;
17 |
18 | public Constraint(RigidBody body1, RigidBody body2)
19 | {
20 | this.body1 = body1;
21 | this.body2 = body2;
22 |
23 | instance = Interlocked.Increment(ref instanceCount);
24 |
25 | body1?.Update();
26 | body2?.Update();
27 | }
28 |
29 | public abstract void PrepareForIteration(float timestep);
30 |
31 | public abstract void Iterate();
32 |
33 | public int CompareTo(Constraint other)
34 | {
35 | if (other.instance < instance)
36 | {
37 | return -1;
38 | }
39 | else if (other.instance > instance)
40 | {
41 | return 1;
42 | }
43 | else
44 | {
45 | return 0;
46 | }
47 | }
48 |
49 | public virtual void DebugDraw(IDebugDrawer drawer)
50 | {
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/source/Jitter/Dynamics/Constraints/FixedAngle.cs:
--------------------------------------------------------------------------------
1 | using Jitter.LinearMath;
2 | using System;
3 |
4 | namespace Jitter.Dynamics.Constraints
5 | {
6 | public class FixedAngle : Constraint
7 | {
8 | private JVector accumulatedImpulse;
9 |
10 | private JMatrix initialOrientation1;
11 | private JMatrix initialOrientation2;
12 |
13 | public FixedAngle(RigidBody body1, RigidBody body2) : base(body1, body2)
14 | {
15 | initialOrientation1 = body1.orientation;
16 | initialOrientation2 = body2.orientation;
17 | }
18 |
19 | public JVector AppliedImpulse => accumulatedImpulse;
20 |
21 | public JMatrix InitialOrientationBody1
22 | {
23 | get => initialOrientation1;
24 | set => initialOrientation1 = value;
25 | }
26 |
27 | public JMatrix InitialOrientationBody2
28 | {
29 | get => initialOrientation2;
30 | set => initialOrientation2 = value;
31 | }
32 |
33 | public float Softness { get; set; }
34 |
35 | public float BiasFactor { get; set; } = 0.05f;
36 |
37 | private JMatrix effectiveMass;
38 | private JVector bias;
39 | private float softnessOverDt;
40 |
41 | public override void PrepareForIteration(float timestep)
42 | {
43 | effectiveMass = body1.invInertiaWorld + body2.invInertiaWorld;
44 |
45 | softnessOverDt = Softness / timestep;
46 |
47 | effectiveMass = JMatrix.FromDiagonal(
48 | m11: effectiveMass.M11 + softnessOverDt,
49 | m22: effectiveMass.M22 + softnessOverDt,
50 | m33: effectiveMass.M33 + softnessOverDt);
51 |
52 | JMatrix.Inverse(effectiveMass, out effectiveMass);
53 |
54 | JMatrix.Multiply(initialOrientation1, initialOrientation2, out var orientationDifference);
55 | JMatrix.Transpose(orientationDifference, out orientationDifference);
56 |
57 | var q = orientationDifference * body2.invOrientation * body1.orientation;
58 | JVector axis;
59 |
60 | float x = q.M32 - q.M23;
61 | float y = q.M13 - q.M31;
62 | float z = q.M21 - q.M12;
63 |
64 | float r = JMath.Sqrt((x * x) + (y * y) + (z * z));
65 | float t = q.M11 + q.M22 + q.M33;
66 |
67 | float angle = (float)Math.Atan2(r, t - 1);
68 | axis = new JVector(x, y, z) * angle;
69 |
70 | if (r != 0.0f)
71 | {
72 | axis = axis * (1.0f / r);
73 | }
74 |
75 | bias = axis * BiasFactor * (-1.0f / timestep);
76 |
77 | if (!body1.IsStatic)
78 | {
79 | body1.angularVelocity += JVector.Transform(accumulatedImpulse, body1.invInertiaWorld);
80 | }
81 |
82 | if (!body2.IsStatic)
83 | {
84 | body2.angularVelocity += JVector.Transform(-1.0f * accumulatedImpulse, body2.invInertiaWorld);
85 | }
86 | }
87 |
88 | public override void Iterate()
89 | {
90 | var jv = body1.angularVelocity - body2.angularVelocity;
91 |
92 | var softnessVector = accumulatedImpulse * softnessOverDt;
93 |
94 | var lambda = -1.0f * JVector.Transform(jv + bias + softnessVector, effectiveMass);
95 |
96 | accumulatedImpulse += lambda;
97 |
98 | if (!body1.IsStatic)
99 | {
100 | body1.angularVelocity += JVector.Transform(lambda, body1.invInertiaWorld);
101 | }
102 |
103 | if (!body2.IsStatic)
104 | {
105 | body2.angularVelocity += JVector.Transform(-1.0f * lambda, body2.invInertiaWorld);
106 | }
107 | }
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/source/Jitter/Dynamics/Constraints/PointOnLine.cs:
--------------------------------------------------------------------------------
1 | using Jitter.LinearMath;
2 |
3 | namespace Jitter.Dynamics.Constraints
4 | {
5 | public class PointOnLine : Constraint
6 | {
7 | private JVector lineNormal;
8 | private JVector localAnchor1;
9 | private JVector localAnchor2;
10 | private JVector r1;
11 | private JVector r2;
12 |
13 | public PointOnLine(RigidBody body1, RigidBody body2, JVector lineStartPointBody1, JVector pointBody2) : base(body1, body2)
14 | {
15 | JVector.Subtract(lineStartPointBody1, body1.position, out localAnchor1);
16 | JVector.Subtract(pointBody2, body2.position, out localAnchor2);
17 |
18 | JVector.Transform(localAnchor1, body1.invOrientation, out localAnchor1);
19 | JVector.Transform(localAnchor2, body2.invOrientation, out localAnchor2);
20 |
21 | lineNormal = JVector.Normalize(lineStartPointBody1 - pointBody2);
22 | }
23 |
24 | public float AppliedImpulse { get; private set; }
25 |
26 | public float Softness { get; set; }
27 |
28 | public float BiasFactor { get; set; } = 0.5f;
29 |
30 | private float effectiveMass;
31 | private float bias;
32 | private float softnessOverDt;
33 | private readonly JVector[] jacobian = new JVector[4];
34 |
35 | public override void PrepareForIteration(float timestep)
36 | {
37 | JVector.Transform(localAnchor1, body1.orientation, out r1);
38 | JVector.Transform(localAnchor2, body2.orientation, out r2);
39 |
40 | JVector.Add(body1.position, r1, out var p1);
41 | JVector.Add(body2.position, r2, out var p2);
42 | JVector.Subtract(p2, p1, out _);
43 |
44 | var l = JVector.Transform(lineNormal, body1.orientation);
45 | l = JVector.Normalize(l);
46 |
47 | var t = (p1 - p2) % l;
48 | if (t.LengthSquared() != 0.0f)
49 | {
50 | t = JVector.Normalize(t);
51 | }
52 |
53 | t %= l;
54 |
55 | jacobian[0] = t;
56 | jacobian[1] = (r1 + p2 - p1) % t;
57 | jacobian[2] = -1.0f * t;
58 | jacobian[3] = -1.0f * r2 % t;
59 |
60 | effectiveMass = body1.inverseMass + body2.inverseMass
61 | + (JVector.Transform(jacobian[1], body1.invInertiaWorld) * jacobian[1])
62 | + (JVector.Transform(jacobian[3], body2.invInertiaWorld) * jacobian[3]);
63 |
64 | softnessOverDt = Softness / timestep;
65 | effectiveMass += softnessOverDt;
66 |
67 | if (effectiveMass != 0)
68 | {
69 | effectiveMass = 1.0f / effectiveMass;
70 | }
71 |
72 | bias = -(l % (p2 - p1)).Length() * BiasFactor * (1.0f / timestep);
73 |
74 | if (!body1.isStatic)
75 | {
76 | body1.linearVelocity += body1.inverseMass * AppliedImpulse * jacobian[0];
77 | body1.angularVelocity += JVector.Transform(AppliedImpulse * jacobian[1], body1.invInertiaWorld);
78 | }
79 |
80 | if (!body2.isStatic)
81 | {
82 | body2.linearVelocity += body2.inverseMass * AppliedImpulse * jacobian[2];
83 | body2.angularVelocity += JVector.Transform(AppliedImpulse * jacobian[3], body2.invInertiaWorld);
84 | }
85 | }
86 |
87 | public override void Iterate()
88 | {
89 | float jv =
90 | (body1.linearVelocity * jacobian[0])
91 | + (body1.angularVelocity * jacobian[1])
92 | + (body2.linearVelocity * jacobian[2])
93 | + (body2.angularVelocity * jacobian[3]);
94 |
95 | float softnessScalar = AppliedImpulse * softnessOverDt;
96 |
97 | float lambda = -effectiveMass * (jv + bias + softnessScalar);
98 |
99 | AppliedImpulse += lambda;
100 |
101 | if (!body1.isStatic)
102 | {
103 | body1.linearVelocity += body1.inverseMass * lambda * jacobian[0];
104 | body1.angularVelocity += JVector.Transform(lambda * jacobian[1], body1.invInertiaWorld);
105 | }
106 |
107 | if (!body2.isStatic)
108 | {
109 | body2.linearVelocity += body2.inverseMass * lambda * jacobian[2];
110 | body2.angularVelocity += JVector.Transform(lambda * jacobian[3], body2.invInertiaWorld);
111 | }
112 | }
113 |
114 | public override void DebugDraw(IDebugDrawer drawer)
115 | {
116 | drawer.DrawLine(body1.position + r1,
117 | body1.position + r1 + (JVector.Transform(lineNormal, body1.orientation) * 100.0f));
118 | }
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/source/Jitter/Dynamics/Constraints/PointOnPoint.cs:
--------------------------------------------------------------------------------
1 | using Jitter.LinearMath;
2 |
3 | namespace Jitter.Dynamics.Constraints
4 | {
5 | public class PointOnPoint : Constraint
6 | {
7 | private readonly JVector localAnchor1;
8 | private readonly JVector localAnchor2;
9 | private JVector r1;
10 | private JVector r2;
11 |
12 | public PointOnPoint(RigidBody body1, RigidBody body2, JVector anchor) : base(body1, body2)
13 | {
14 | JVector.Subtract(anchor, body1.position, out localAnchor1);
15 | JVector.Subtract(anchor, body2.position, out localAnchor2);
16 |
17 | JVector.Transform(localAnchor1, body1.invOrientation, out localAnchor1);
18 | JVector.Transform(localAnchor2, body2.invOrientation, out localAnchor2);
19 | }
20 |
21 | public float AppliedImpulse { get; private set; }
22 |
23 | public float Softness { get; set; } = 0.01f;
24 |
25 | public float BiasFactor { get; set; } = 0.05f;
26 |
27 | private float effectiveMass;
28 | private float bias;
29 | private float softnessOverDt;
30 | private readonly JVector[] jacobian = new JVector[4];
31 |
32 | public override void PrepareForIteration(float timestep)
33 | {
34 | JVector.Transform(localAnchor1, body1.orientation, out r1);
35 | JVector.Transform(localAnchor2, body2.orientation, out r2);
36 |
37 | JVector.Add(body1.position, r1, out var p1);
38 | JVector.Add(body2.position, r2, out var p2);
39 |
40 | JVector.Subtract(p2, p1, out var dp);
41 |
42 | float deltaLength = dp.Length();
43 |
44 | var n = p2 - p1;
45 | if (n.LengthSquared() != 0.0f)
46 | {
47 | n = JVector.Normalize(n);
48 | }
49 |
50 | jacobian[0] = -1.0f * n;
51 | jacobian[1] = -1.0f * (r1 % n);
52 | jacobian[2] = 1.0f * n;
53 | jacobian[3] = r2 % n;
54 |
55 | effectiveMass = body1.inverseMass + body2.inverseMass
56 | + (JVector.Transform(jacobian[1], body1.invInertiaWorld) * jacobian[1])
57 | + (JVector.Transform(jacobian[3], body2.invInertiaWorld) * jacobian[3]);
58 |
59 | softnessOverDt = Softness / timestep;
60 | effectiveMass += softnessOverDt;
61 |
62 | effectiveMass = 1.0f / effectiveMass;
63 |
64 | bias = deltaLength * BiasFactor * (1.0f / timestep);
65 |
66 | if (!body1.isStatic)
67 | {
68 | body1.linearVelocity += body1.inverseMass * AppliedImpulse * jacobian[0];
69 | body1.angularVelocity += JVector.Transform(AppliedImpulse * jacobian[1], body1.invInertiaWorld);
70 | }
71 |
72 | if (!body2.isStatic)
73 | {
74 | body2.linearVelocity += body2.inverseMass * AppliedImpulse * jacobian[2];
75 | body2.angularVelocity += JVector.Transform(AppliedImpulse * jacobian[3], body2.invInertiaWorld);
76 | }
77 | }
78 |
79 | public override void Iterate()
80 | {
81 | float jv =
82 | (body1.linearVelocity * jacobian[0])
83 | + (body1.angularVelocity * jacobian[1])
84 | + (body2.linearVelocity * jacobian[2])
85 | + (body2.angularVelocity * jacobian[3]);
86 |
87 | float softnessScalar = AppliedImpulse * softnessOverDt;
88 |
89 | float lambda = -effectiveMass * (jv + bias + softnessScalar);
90 |
91 | AppliedImpulse += lambda;
92 |
93 | if (!body1.isStatic)
94 | {
95 | body1.linearVelocity += body1.inverseMass * lambda * jacobian[0];
96 | body1.angularVelocity += JVector.Transform(lambda * jacobian[1], body1.invInertiaWorld);
97 | }
98 |
99 | if (!body2.isStatic)
100 | {
101 | body2.linearVelocity += body2.inverseMass * lambda * jacobian[2];
102 | body2.angularVelocity += JVector.Transform(lambda * jacobian[3], body2.invInertiaWorld);
103 | }
104 | }
105 |
106 | public override void DebugDraw(IDebugDrawer drawer)
107 | {
108 | drawer.DrawLine(body1.position, body1.position + r1);
109 | drawer.DrawLine(body2.position, body2.position + r2);
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/source/Jitter/Dynamics/Constraints/SingleBody/FixedAngle.cs:
--------------------------------------------------------------------------------
1 | using Jitter.LinearMath;
2 | using System;
3 |
4 | namespace Jitter.Dynamics.Constraints.SingleBody
5 | {
6 | public class FixedAngle : Constraint
7 | {
8 | private JMatrix orientation;
9 | private JVector accumulatedImpulse;
10 |
11 | public FixedAngle(RigidBody body1) : base(body1, null)
12 | {
13 | orientation = body1.orientation;
14 | }
15 |
16 | public float Softness { get; set; }
17 |
18 | public float BiasFactor { get; set; } = 0.05f;
19 |
20 | public JMatrix InitialOrientation { get => orientation; set => orientation = value; }
21 |
22 | private JMatrix effectiveMass;
23 | private JVector bias;
24 | private float softnessOverDt;
25 |
26 | public override void PrepareForIteration(float timestep)
27 | {
28 | effectiveMass = body1.invInertiaWorld;
29 |
30 | softnessOverDt = Softness / timestep;
31 |
32 | effectiveMass = JMatrix.FromDiagonal(
33 | m11: effectiveMass.M11 + softnessOverDt,
34 | m22: effectiveMass.M22 + softnessOverDt,
35 | m33: effectiveMass.M33 + softnessOverDt);
36 |
37 | JMatrix.Inverse(effectiveMass, out effectiveMass);
38 |
39 | var q = JMatrix.Transpose(orientation) * body1.orientation;
40 |
41 | float x = q.M32 - q.M23;
42 | float y = q.M13 - q.M31;
43 | float z = q.M21 - q.M12;
44 |
45 | float r = JMath.Sqrt((x * x) + (y * y) + (z * z));
46 | float t = q.M11 + q.M22 + q.M33;
47 |
48 | float angle = (float)Math.Atan2(r, t - 1);
49 | var axis = new JVector(x, y, z) * angle;
50 |
51 | if (r != 0.0f)
52 | {
53 | axis *= 1.0f / r;
54 | }
55 |
56 | bias = axis * BiasFactor * (-1.0f / timestep);
57 |
58 | if (!body1.IsStatic)
59 | {
60 | body1.angularVelocity += JVector.Transform(accumulatedImpulse, body1.invInertiaWorld);
61 | }
62 | }
63 |
64 | public override void Iterate()
65 | {
66 | var jv = body1.angularVelocity;
67 |
68 | var softnessVector = accumulatedImpulse * softnessOverDt;
69 |
70 | var lambda = -1.0f * JVector.Transform(jv + bias + softnessVector, effectiveMass);
71 |
72 | accumulatedImpulse += lambda;
73 |
74 | if (!body1.IsStatic)
75 | {
76 | body1.angularVelocity += JVector.Transform(lambda, body1.invInertiaWorld);
77 | }
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/source/Jitter/Dynamics/Constraints/SingleBody/PointOnLine.cs:
--------------------------------------------------------------------------------
1 | using Jitter.LinearMath;
2 | using System;
3 |
4 | namespace Jitter.Dynamics.Constraints.SingleBody
5 | {
6 | public class PointOnLine : Constraint
7 | {
8 | private readonly JVector localAnchor1;
9 | private JVector r1;
10 |
11 | private JVector lineNormal = JVector.Right;
12 | private JVector anchor;
13 |
14 | public PointOnLine(RigidBody body, JVector localAnchor, JVector lineDirection) : base(body, null)
15 | {
16 | if (lineDirection.LengthSquared() == 0.0f)
17 | {
18 | throw new ArgumentException("Line direction can't be zero", nameof(lineDirection));
19 | }
20 |
21 | localAnchor1 = localAnchor;
22 | anchor = body.position + JVector.Transform(localAnchor, body.orientation);
23 |
24 | lineNormal = lineDirection;
25 | lineNormal = JVector.Normalize(lineNormal);
26 | }
27 |
28 | public JVector Anchor { get => anchor; set => anchor = value; }
29 |
30 | public JVector Axis
31 | {
32 | get => lineNormal;
33 | set
34 | {
35 | lineNormal = value;
36 | lineNormal = JVector.Normalize(lineNormal);
37 | }
38 | }
39 |
40 | public float Softness { get; set; }
41 |
42 | public float BiasFactor { get; set; } = 0.5f;
43 |
44 | private float effectiveMass;
45 | private float accumulatedImpulse;
46 | private float bias;
47 | private float softnessOverDt;
48 | private readonly JVector[] jacobian = new JVector[2];
49 |
50 | public override void PrepareForIteration(float timestep)
51 | {
52 | JVector.Transform(localAnchor1, body1.orientation, out r1);
53 |
54 | JVector.Add(body1.position, r1, out var p1);
55 |
56 | JVector.Subtract(p1, anchor, out var dp);
57 |
58 | var l = lineNormal;
59 |
60 | var t = (p1 - anchor) % l;
61 | if (t.LengthSquared() != 0.0f)
62 | {
63 | t = JVector.Normalize(t);
64 | }
65 |
66 | t %= l;
67 |
68 | jacobian[0] = t;
69 | jacobian[1] = r1 % t;
70 |
71 | effectiveMass = body1.inverseMass
72 | + (JVector.Transform(jacobian[1], body1.invInertiaWorld) * jacobian[1]);
73 |
74 | softnessOverDt = Softness / timestep;
75 | effectiveMass += softnessOverDt;
76 |
77 | if (effectiveMass != 0)
78 | {
79 | effectiveMass = 1.0f / effectiveMass;
80 | }
81 |
82 | bias = -(l % (p1 - anchor)).Length() * BiasFactor * (1.0f / timestep);
83 |
84 | if (!body1.isStatic)
85 | {
86 | body1.linearVelocity += body1.inverseMass * accumulatedImpulse * jacobian[0];
87 | body1.angularVelocity += JVector.Transform(accumulatedImpulse * jacobian[1], body1.invInertiaWorld);
88 | }
89 | }
90 |
91 | public override void Iterate()
92 | {
93 | float jv =
94 | (body1.linearVelocity * jacobian[0])
95 | + (body1.angularVelocity * jacobian[1]);
96 |
97 | float softnessScalar = accumulatedImpulse * softnessOverDt;
98 |
99 | float lambda = -effectiveMass * (jv + bias + softnessScalar);
100 |
101 | accumulatedImpulse += lambda;
102 |
103 | if (!body1.isStatic)
104 | {
105 | body1.linearVelocity += body1.inverseMass * lambda * jacobian[0];
106 | body1.angularVelocity += JVector.Transform(lambda * jacobian[1], body1.invInertiaWorld);
107 | }
108 | }
109 |
110 | public override void DebugDraw(IDebugDrawer drawer)
111 | {
112 | drawer.DrawLine(anchor - (lineNormal * 50.0f), anchor + (lineNormal * 50.0f));
113 | drawer.DrawLine(body1.position, body1.position + r1);
114 | }
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/source/Jitter/Dynamics/Constraints/SingleBody/PointOnPoint.cs:
--------------------------------------------------------------------------------
1 | using Jitter.LinearMath;
2 |
3 | namespace Jitter.Dynamics.Constraints.SingleBody
4 | {
5 | public class PointOnPoint : Constraint
6 | {
7 | private JVector localAnchor1;
8 | private JVector anchor;
9 |
10 | private JVector r1;
11 |
12 | public PointOnPoint(RigidBody body, JVector localAnchor) : base(body, null)
13 | {
14 | localAnchor1 = localAnchor;
15 |
16 | anchor = body.position + JVector.Transform(localAnchor, body.orientation);
17 | }
18 |
19 | public float AppliedImpulse { get; private set; }
20 |
21 | public float Softness { get; set; } = 0.01f;
22 |
23 | public JVector Anchor { get => anchor; set => anchor = value; }
24 |
25 | public float BiasFactor { get; set; } = 0.1f;
26 |
27 | private float effectiveMass;
28 | private float bias;
29 | private float softnessOverDt;
30 | private readonly JVector[] jacobian = new JVector[2];
31 |
32 | public override void PrepareForIteration(float timestep)
33 | {
34 | JVector.Transform(localAnchor1, body1.orientation, out r1);
35 | JVector.Add( body1.position, r1, out var p1);
36 | JVector.Subtract(p1, anchor, out var dp);
37 |
38 | float deltaLength = dp.Length();
39 |
40 | var n = anchor - p1;
41 | if (n.LengthSquared() != 0.0f)
42 | {
43 | n = JVector.Normalize(n);
44 | }
45 |
46 | jacobian[0] = -1.0f * n;
47 | jacobian[1] = -1.0f * (r1 % n);
48 |
49 | effectiveMass = body1.inverseMass + (JVector.Transform(jacobian[1], body1.invInertiaWorld) * jacobian[1]);
50 |
51 | softnessOverDt = Softness / timestep;
52 | effectiveMass += softnessOverDt;
53 |
54 | effectiveMass = 1.0f / effectiveMass;
55 |
56 | bias = deltaLength * BiasFactor * (1.0f / timestep);
57 |
58 | if (!body1.isStatic)
59 | {
60 | body1.linearVelocity += body1.inverseMass * AppliedImpulse * jacobian[0];
61 | body1.angularVelocity += JVector.Transform(AppliedImpulse * jacobian[1], body1.invInertiaWorld);
62 | }
63 | }
64 |
65 | public override void Iterate()
66 | {
67 | float jv =
68 | (body1.linearVelocity * jacobian[0])
69 | + (body1.angularVelocity * jacobian[1]);
70 |
71 | float softnessScalar = AppliedImpulse * softnessOverDt;
72 |
73 | float lambda = -effectiveMass * (jv + bias + softnessScalar);
74 |
75 | AppliedImpulse += lambda;
76 |
77 | if (!body1.isStatic)
78 | {
79 | body1.linearVelocity += body1.inverseMass * lambda * jacobian[0];
80 | body1.angularVelocity += JVector.Transform(lambda * jacobian[1], body1.invInertiaWorld);
81 | }
82 | }
83 |
84 | public override void DebugDraw(IDebugDrawer drawer)
85 | {
86 | drawer.DrawPoint(anchor);
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/source/Jitter/Dynamics/ContactSettings.cs:
--------------------------------------------------------------------------------
1 | namespace Jitter.Dynamics
2 | {
3 | public class ContactSettings
4 | {
5 | public enum MaterialCoefficientMixingType { TakeMaximum, TakeMinimum, UseAverage }
6 |
7 | internal float maximumBias = 10.0f;
8 | internal float bias = 0.25f;
9 | internal float minVelocity = 0.001f;
10 | internal float allowedPenetration = 0.01f;
11 | internal float breakThreshold = 0.01f;
12 |
13 | internal MaterialCoefficientMixingType materialMode = MaterialCoefficientMixingType.UseAverage;
14 |
15 | public float MaximumBias { get => maximumBias; set => maximumBias = value; }
16 |
17 | public float BiasFactor { get => bias; set => bias = value; }
18 |
19 | public float MinimumVelocity { get => minVelocity; set => minVelocity = value; }
20 |
21 | public float AllowedPenetration { get => allowedPenetration; set => allowedPenetration = value; }
22 |
23 | public float BreakThreshold { get => breakThreshold; set => breakThreshold = value; }
24 |
25 | public MaterialCoefficientMixingType MaterialCoefficientMixing { get => materialMode; set => materialMode = value; }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/source/Jitter/Dynamics/IConstraint.cs:
--------------------------------------------------------------------------------
1 | namespace Jitter.Dynamics
2 | {
3 | public interface IConstraint
4 | {
5 |
6 | RigidBody Body1 { get; }
7 |
8 | RigidBody Body2 { get; }
9 |
10 | ///
11 | /// Called once before iteration starts.
12 | ///
13 | /// The simulation timestep
14 | void PrepareForIteration(float timestep);
15 |
16 | ///
17 | /// Iteratively solve this constraint.
18 | ///
19 | void Iterate();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/source/Jitter/Dynamics/Joints/HingeJoint.cs:
--------------------------------------------------------------------------------
1 | using Jitter.Dynamics.Constraints;
2 | using Jitter.LinearMath;
3 |
4 | namespace Jitter.Dynamics.Joints
5 | {
6 | public class HingeJoint : Joint
7 | {
8 | private readonly PointOnPoint[] worldPointConstraint;
9 |
10 | public PointOnPoint PointConstraint1 => worldPointConstraint[0];
11 | public PointOnPoint PointConstraint2 => worldPointConstraint[1];
12 |
13 | public HingeJoint(World world, RigidBody body1, RigidBody body2, JVector position, JVector hingeAxis) : base(world)
14 | {
15 | worldPointConstraint = new PointOnPoint[2];
16 |
17 | hingeAxis *= 0.5f;
18 |
19 | var pos1 = position; JVector.Add(pos1, hingeAxis, out pos1);
20 | var pos2 = position; JVector.Subtract(pos2, hingeAxis, out pos2);
21 |
22 | worldPointConstraint[0] = new PointOnPoint(body1, body2, pos1);
23 | worldPointConstraint[1] = new PointOnPoint(body1, body2, pos2);
24 | }
25 |
26 | public PointOnPoint PointOnPointConstraint1 => worldPointConstraint[0];
27 |
28 | public PointOnPoint PointOnPointConstraint2 => worldPointConstraint[1];
29 |
30 | public float AppliedImpulse => worldPointConstraint[0].AppliedImpulse + worldPointConstraint[1].AppliedImpulse;
31 |
32 | public override void Activate()
33 | {
34 | World.AddConstraint(worldPointConstraint[0]);
35 | World.AddConstraint(worldPointConstraint[1]);
36 | }
37 |
38 | public override void Deactivate()
39 | {
40 | World.RemoveConstraint(worldPointConstraint[0]);
41 | World.RemoveConstraint(worldPointConstraint[1]);
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/source/Jitter/Dynamics/Joints/Joint.cs:
--------------------------------------------------------------------------------
1 | namespace Jitter.Dynamics.Joints
2 | {
3 | public abstract class Joint
4 | {
5 | public World World { get; }
6 |
7 | public Joint(World world)
8 | {
9 | World = world;
10 | }
11 |
12 | public abstract void Activate();
13 |
14 | public abstract void Deactivate();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/source/Jitter/Dynamics/Joints/LimitedHingeJoint.cs:
--------------------------------------------------------------------------------
1 | using Jitter.Dynamics.Constraints;
2 | using Jitter.LinearMath;
3 |
4 | namespace Jitter.Dynamics.Joints
5 | {
6 | public class LimitedHingeJoint : Joint
7 | {
8 | private readonly PointOnPoint[] worldPointConstraint;
9 |
10 | public PointOnPoint PointConstraint1 => worldPointConstraint[0];
11 | public PointOnPoint PointConstraint2 => worldPointConstraint[1];
12 |
13 | public PointPointDistance DistanceConstraint { get; }
14 |
15 | public LimitedHingeJoint(World world, RigidBody body1, RigidBody body2, JVector position, JVector hingeAxis, float hingeFwdAngle, float hingeBckAngle) : base(world)
16 | {
17 | worldPointConstraint = new PointOnPoint[2];
18 |
19 | hingeAxis *= 0.5f;
20 |
21 | var pos1 = position;
22 | JVector.Add(pos1, hingeAxis, out pos1);
23 | var pos2 = position;
24 | JVector.Subtract(pos2, hingeAxis, out pos2);
25 |
26 | worldPointConstraint[0] = new PointOnPoint(body1, body2, pos1);
27 | worldPointConstraint[1] = new PointOnPoint(body1, body2, pos2);
28 |
29 | hingeAxis = JVector.Normalize(hingeAxis);
30 |
31 | var perpDir = JVector.Up;
32 |
33 | if (JVector.Dot(perpDir, hingeAxis) > 0.1f)
34 | {
35 | perpDir = JVector.Right;
36 | }
37 |
38 | var sideAxis = JVector.Cross(hingeAxis, perpDir);
39 | perpDir = JVector.Cross(sideAxis, hingeAxis);
40 | perpDir = JVector.Normalize(perpDir);
41 |
42 | float len = 10.0f * 3;
43 |
44 | var hingeRelAnchorPos0 = perpDir * len;
45 |
46 | float angleToMiddle = 0.5f * (hingeFwdAngle - hingeBckAngle);
47 | var hingeRelAnchorPos1 = JVector.Transform(hingeRelAnchorPos0, JMatrix.CreateFromAxisAngle(hingeAxis, -angleToMiddle / 360.0f * 2.0f * JMath.Pi));
48 |
49 | float hingeHalfAngle = 0.5f * (hingeFwdAngle + hingeBckAngle);
50 | float allowedDistance = len * 2.0f * (float)System.Math.Sin(hingeHalfAngle * 0.5f / 360.0f * 2.0f * JMath.Pi);
51 |
52 | var hingePos = body1.Position;
53 | var relPos0c = hingePos + hingeRelAnchorPos0;
54 | var relPos1c = hingePos + hingeRelAnchorPos1;
55 |
56 | DistanceConstraint = new PointPointDistance(body1, body2, relPos0c, relPos1c)
57 | {
58 | Distance = allowedDistance,
59 | Behavior = PointPointDistance.DistanceBehavior.LimitMaximumDistance
60 | };
61 | }
62 |
63 | public override void Activate()
64 | {
65 | World.AddConstraint(worldPointConstraint[0]);
66 | World.AddConstraint(worldPointConstraint[1]);
67 | World.AddConstraint(DistanceConstraint);
68 | }
69 |
70 | public override void Deactivate()
71 | {
72 | World.RemoveConstraint(worldPointConstraint[0]);
73 | World.RemoveConstraint(worldPointConstraint[1]);
74 | World.RemoveConstraint(DistanceConstraint);
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/source/Jitter/Dynamics/Joints/PrismaticJoint.cs:
--------------------------------------------------------------------------------
1 |
2 | using Jitter.Dynamics.Constraints;
3 | using Jitter.LinearMath;
4 |
5 | namespace Jitter.Dynamics.Joints
6 | {
7 | public class PrismaticJoint : Joint
8 | {
9 | public PointPointDistance MaximumDistanceConstraint { get; }
10 | public PointPointDistance MinimumDistanceConstraint { get; }
11 |
12 | public FixedAngle FixedAngleConstraint { get; }
13 | public PointOnLine PointOnLineConstraint { get; }
14 |
15 | public PrismaticJoint(World world, RigidBody body1, RigidBody body2) : base(world)
16 | {
17 | FixedAngleConstraint = new FixedAngle(body1, body2);
18 | PointOnLineConstraint = new PointOnLine(body1, body2, body1.position, body2.position);
19 | }
20 |
21 | public PrismaticJoint(World world, RigidBody body1, RigidBody body2, float minimumDistance, float maximumDistance)
22 | : base(world)
23 | {
24 | FixedAngleConstraint = new FixedAngle(body1, body2);
25 | PointOnLineConstraint = new PointOnLine(body1, body2, body1.position, body2.position);
26 |
27 | MinimumDistanceConstraint = new PointPointDistance(body1, body2, body1.position, body2.position)
28 | {
29 | Behavior = PointPointDistance.DistanceBehavior.LimitMinimumDistance,
30 | Distance = minimumDistance
31 | };
32 |
33 | MaximumDistanceConstraint = new PointPointDistance(body1, body2, body1.position, body2.position)
34 | {
35 | Behavior = PointPointDistance.DistanceBehavior.LimitMaximumDistance,
36 | Distance = maximumDistance
37 | };
38 | }
39 |
40 | public PrismaticJoint(World world, RigidBody body1, RigidBody body2, JVector pointOnBody1, JVector pointOnBody2)
41 | : base(world)
42 | {
43 | FixedAngleConstraint = new FixedAngle(body1, body2);
44 | PointOnLineConstraint = new PointOnLine(body1, body2, pointOnBody1, pointOnBody2);
45 | }
46 |
47 | public PrismaticJoint(World world, RigidBody body1, RigidBody body2, JVector pointOnBody1, JVector pointOnBody2, float maximumDistance, float minimumDistance)
48 | : base(world)
49 | {
50 | FixedAngleConstraint = new FixedAngle(body1, body2);
51 | PointOnLineConstraint = new PointOnLine(body1, body2, pointOnBody1, pointOnBody2);
52 | }
53 |
54 | public override void Activate()
55 | {
56 | if (MaximumDistanceConstraint != null)
57 | {
58 | World.AddConstraint(MaximumDistanceConstraint);
59 | }
60 |
61 | if (MinimumDistanceConstraint != null)
62 | {
63 | World.AddConstraint(MinimumDistanceConstraint);
64 | }
65 |
66 | World.AddConstraint(FixedAngleConstraint);
67 | World.AddConstraint(PointOnLineConstraint);
68 | }
69 |
70 | public override void Deactivate()
71 | {
72 | if (MaximumDistanceConstraint != null)
73 | {
74 | World.RemoveConstraint(MaximumDistanceConstraint);
75 | }
76 |
77 | if (MinimumDistanceConstraint != null)
78 | {
79 | World.RemoveConstraint(MinimumDistanceConstraint);
80 | }
81 |
82 | World.RemoveConstraint(FixedAngleConstraint);
83 | World.RemoveConstraint(PointOnLineConstraint);
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/source/Jitter/Dynamics/Material.cs:
--------------------------------------------------------------------------------
1 | namespace Jitter.Dynamics
2 | {
3 | public class Material
4 | {
5 | internal float kineticFriction = 0.3f;
6 | internal float staticFriction = 0.6f;
7 | internal float restitution;
8 |
9 | public float Restitution
10 | {
11 | get => restitution;
12 | set => restitution = value;
13 | }
14 |
15 | public float StaticFriction
16 | {
17 | get => staticFriction;
18 | set => staticFriction = value;
19 | }
20 |
21 | public float KineticFriction
22 | {
23 | get => kineticFriction;
24 | set => kineticFriction = value;
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/source/Jitter/IDebugDraw.cs:
--------------------------------------------------------------------------------
1 | using Jitter.LinearMath;
2 |
3 | namespace Jitter
4 | {
5 | public interface IDebugDrawable
6 | {
7 | void DebugDraw(IDebugDrawer drawer);
8 | }
9 |
10 | public interface IDebugDrawer
11 | {
12 | void DrawLine(JVector start, JVector end);
13 | void DrawPoint(JVector pos);
14 | void DrawTriangle(JVector pos1, JVector pos2, JVector pos3);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/source/Jitter/Jitter.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard2.0
4 | JitterPhysics
5 | Copyright (c) 2019 Thorben Linneweber, Matthew Leibowitz, Flurin Feuerstein
6 | 0.2.0.0
7 | Thorben Linneweber, Matthew Leibowitz, Flurin Feuerstein
8 |
9 | Realtime physics engine for .NET
10 | Jitter Physics is a fast and lightweight physics engine written in C#
11 | LICENSE.md
12 | true
13 | https://github.com/fxredeemer/jitterphysics
14 | Jitter, Physics, 3D
15 | true
16 |
17 |
18 |
19 |
20 |
21 |
22 | True
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/source/Jitter/LinearMath/JConvexHull.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Jitter.LinearMath
5 | {
6 | public static class JConvexHull
7 | {
8 | public enum Approximation
9 | {
10 | Level1 = 6,
11 | Level2 = 7,
12 | Level3 = 8,
13 | Level4 = 9,
14 | Level5 = 10,
15 | Level6 = 11,
16 | Level7 = 12,
17 | Level8 = 13,
18 | Level9 = 15,
19 | Level10 = 20,
20 | Level15 = 25,
21 | Level20 = 30
22 | }
23 |
24 | public static int[] Build(List pointCloud, Approximation factor)
25 | {
26 | var allIndices = new List();
27 |
28 | int steps = (int)factor;
29 |
30 | for (int thetaIndex = 0; thetaIndex < steps; thetaIndex++)
31 | {
32 | float theta = JMath.Pi / (steps - 1) * thetaIndex;
33 | float sinTheta = (float)Math.Sin(theta);
34 | float cosTheta = (float)Math.Cos(theta);
35 |
36 | for (int phiIndex = 0; phiIndex < steps; phiIndex++)
37 | {
38 | float phi = (2.0f * JMath.Pi / (steps - 0) * phiIndex) - JMath.Pi;
39 | float sinPhi = (float)Math.Sin(phi);
40 | float cosPhi = (float)Math.Cos(phi);
41 |
42 | var dir = new JVector(sinTheta * cosPhi, cosTheta, sinTheta * sinPhi);
43 |
44 | int index = FindExtremePoint(pointCloud, dir);
45 | allIndices.Add(index);
46 | }
47 | }
48 |
49 | allIndices.Sort();
50 |
51 | for (int i = 1; i < allIndices.Count; i++)
52 | {
53 | if (allIndices[i - 1] == allIndices[i])
54 | {
55 | allIndices.RemoveAt(i - 1); i--;
56 | }
57 | }
58 |
59 | return allIndices.ToArray();
60 | }
61 |
62 | private static int FindExtremePoint(List points, in JVector dir)
63 | {
64 | int index = 0;
65 | float current = float.MinValue;
66 |
67 | JVector point;
68 | float value;
69 |
70 | for (int i = 1; i < points.Count; i++)
71 | {
72 | point = points[i];
73 |
74 | value = JVector.Dot(point, dir);
75 | if (value > current)
76 | {
77 | current = value; index = i;
78 | }
79 | }
80 |
81 | return index;
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/source/Jitter/LinearMath/JMath.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Jitter.LinearMath
4 | {
5 | public sealed class JMath
6 | {
7 | public const float Pi = 3.1415926535f;
8 | public const float PiOver2 = 1.570796326794f;
9 | public const float Epsilon = 1.192092896e-012f;
10 |
11 | public static float Sqrt(float number)
12 | {
13 | return (float)Math.Sqrt(number);
14 | }
15 |
16 | public static float Cos(float number)
17 | {
18 | return (float)Math.Cos(number);
19 | }
20 |
21 | public static float Sin(float number)
22 | {
23 | return (float)Math.Sin(number);
24 | }
25 |
26 | public static float Max(float val1, float val2)
27 | {
28 | return (val1 > val2) ? val1 : val2;
29 | }
30 |
31 | public static float Min(float val1, float val2)
32 | {
33 | return (val1 < val2) ? val1 : val2;
34 | }
35 |
36 | public static float Max(float val1, float val2, float val3)
37 | {
38 | float max12 = (val1 > val2) ? val1 : val2;
39 | return (max12 > val3) ? max12 : val3;
40 | }
41 |
42 | public static float Clamp(float value, float min, float max)
43 | {
44 | value = (value > max) ? max : value;
45 | value = (value < min) ? min : value;
46 | return value;
47 | }
48 |
49 | public static JMatrix Absolute(in JMatrix matrix)
50 | {
51 | Absolute(matrix, out var absolute);
52 | return absolute;
53 | }
54 |
55 | public static void Absolute(in JMatrix matrix, out JMatrix result)
56 | {
57 | result = new JMatrix(
58 | m11: Math.Abs(matrix.M11),
59 | m12: Math.Abs(matrix.M12),
60 | m13: Math.Abs(matrix.M13),
61 | m21: Math.Abs(matrix.M21),
62 | m22: Math.Abs(matrix.M22),
63 | m23: Math.Abs(matrix.M23),
64 | m31: Math.Abs(matrix.M31),
65 | m32: Math.Abs(matrix.M32),
66 | m33: Math.Abs(matrix.M33));
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/source/Jitter/ResourcePool.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Jitter
5 | {
6 | public class ResourcePool
7 | {
8 | private readonly Stack stack = new Stack();
9 |
10 | public void ResetResourcePool()
11 | {
12 | lock (stack)
13 | {
14 | stack.Clear();
15 | }
16 | }
17 |
18 | public int Count => stack.Count;
19 |
20 | public void GiveBack(T obj)
21 | {
22 | lock (stack)
23 | {
24 | stack.Push(obj);
25 | }
26 | }
27 |
28 | public T GetNew()
29 | {
30 | T freeObj;
31 |
32 | lock (stack)
33 | {
34 | if (stack.Count == 0)
35 | {
36 | freeObj = Activator.CreateInstance();
37 | stack.Push(freeObj);
38 | }
39 |
40 | freeObj = stack.Pop();
41 | }
42 |
43 | return freeObj;
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/source/Jitter/ThreadManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading;
4 |
5 | #if PORTABLE
6 | using System.Threading.Tasks;
7 | using Thread = System.Threading.Tasks.Task;
8 | #endif
9 |
10 | namespace Jitter
11 | {
12 | public sealed class ThreadManager
13 | {
14 | public const int ThreadsPerProcessor = 1;
15 |
16 | private ManualResetEvent waitHandleA, waitHandleB;
17 | private ManualResetEvent currentWaitHandle;
18 | private readonly List> tasks = new List>();
19 | private readonly List