1
+ // SPDX-FileCopyrightText: 2025 Erin Catto
2
+ // SPDX-FileCopyrightText: 2025 Ikpil Choi([email protected] )
3
+ // SPDX-License-Identifier: MIT
4
+
5
+ using System . Numerics ;
6
+ using ImGuiNET ;
7
+ using static Box2D . NET . B2Joints ;
8
+ using static Box2D . NET . B2Geometries ;
9
+ using static Box2D . NET . B2Types ;
10
+ using static Box2D . NET . B2MathFunction ;
11
+ using static Box2D . NET . B2Bodies ;
12
+ using static Box2D . NET . B2Shapes ;
13
+ using static Box2D . NET . B2Ids ;
14
+
15
+ namespace Box2D . NET . Samples . Samples . Issues ;
16
+
17
+ public class Crash01 : Sample
18
+ {
19
+ private static readonly int SampleBodyType = SampleFactory . Shared . RegisterSample ( "Issues" , "Crash01" , Create ) ;
20
+
21
+ private B2BodyId m_attachmentId ;
22
+ private B2BodyId m_platformId ;
23
+ private B2BodyType m_type ;
24
+ private bool m_isEnabled ;
25
+
26
+ private static Sample Create ( SampleContext context )
27
+ {
28
+ return new Crash01 ( context ) ;
29
+ }
30
+
31
+ public Crash01 ( SampleContext context ) : base ( context )
32
+ {
33
+ if ( m_context . settings . restart == false )
34
+ {
35
+ m_context . camera . m_center = new B2Vec2 ( 0.8f , 6.4f ) ;
36
+ m_context . camera . m_zoom = 25.0f * 0.4f ;
37
+ }
38
+
39
+ m_type = B2BodyType . b2_dynamicBody ;
40
+ m_isEnabled = true ;
41
+
42
+ B2BodyId groundId = b2_nullBodyId ;
43
+ {
44
+ B2BodyDef bodyDef = b2DefaultBodyDef ( ) ;
45
+ bodyDef . name = "ground" ;
46
+ groundId = b2CreateBody ( m_worldId , ref bodyDef ) ;
47
+
48
+ B2Segment segment = new B2Segment ( new B2Vec2 ( - 20.0f , 0.0f ) , new B2Vec2 ( 20.0f , 0.0f ) ) ;
49
+ B2ShapeDef shapeDef = b2DefaultShapeDef ( ) ;
50
+ b2CreateSegmentShape ( groundId , ref shapeDef , ref segment ) ;
51
+ }
52
+
53
+ // Define attachment
54
+ {
55
+ B2BodyDef bodyDef = b2DefaultBodyDef ( ) ;
56
+ bodyDef . type = B2BodyType . b2_dynamicBody ;
57
+ bodyDef . position = new B2Vec2 ( - 2.0f , 3.0f ) ;
58
+ bodyDef . name = "attach1" ;
59
+ m_attachmentId = b2CreateBody ( m_worldId , ref bodyDef ) ;
60
+
61
+ B2Polygon box = b2MakeBox ( 0.5f , 2.0f ) ;
62
+ B2ShapeDef shapeDef = b2DefaultShapeDef ( ) ;
63
+ shapeDef . density = 1.0f ;
64
+ b2CreatePolygonShape ( m_attachmentId , ref shapeDef , ref box ) ;
65
+ }
66
+
67
+ // Define platform
68
+ {
69
+ B2BodyDef bodyDef = b2DefaultBodyDef ( ) ;
70
+ bodyDef . type = m_type ;
71
+ bodyDef . isEnabled = m_isEnabled ;
72
+ bodyDef . position = new B2Vec2 ( - 4.0f , 5.0f ) ;
73
+ bodyDef . name = "platform" ;
74
+ m_platformId = b2CreateBody ( m_worldId , ref bodyDef ) ;
75
+
76
+ B2Polygon box = b2MakeOffsetBox ( 0.5f , 4.0f , new B2Vec2 ( 4.0f , 0.0f ) , b2MakeRot ( 0.5f * B2_PI ) ) ;
77
+
78
+ B2ShapeDef shapeDef = b2DefaultShapeDef ( ) ;
79
+ shapeDef . density = 2.0f ;
80
+ b2CreatePolygonShape ( m_platformId , ref shapeDef , ref box ) ;
81
+
82
+ B2RevoluteJointDef revoluteDef = b2DefaultRevoluteJointDef ( ) ;
83
+ B2Vec2 pivot = new B2Vec2 ( - 2.0f , 5.0f ) ;
84
+ revoluteDef . @base . bodyIdA = m_attachmentId ;
85
+ revoluteDef . @base . bodyIdB = m_platformId ;
86
+ revoluteDef . @base . localFrameA . p = b2Body_GetLocalPoint ( m_attachmentId , pivot ) ;
87
+ revoluteDef . @base . localFrameB . p = b2Body_GetLocalPoint ( m_platformId , pivot ) ;
88
+ revoluteDef . maxMotorTorque = 50.0f ;
89
+ revoluteDef . enableMotor = true ;
90
+ b2CreateRevoluteJoint ( m_worldId , ref revoluteDef ) ;
91
+
92
+ B2PrismaticJointDef prismaticDef = b2DefaultPrismaticJointDef ( ) ;
93
+ B2Vec2 anchor = new B2Vec2 ( 0.0f , 5.0f ) ;
94
+ prismaticDef . @base . bodyIdA = groundId ;
95
+ prismaticDef . @base . bodyIdB = m_platformId ;
96
+ prismaticDef . @base . localFrameA . p = b2Body_GetLocalPoint ( groundId , anchor ) ;
97
+ prismaticDef . @base . localFrameB . p = b2Body_GetLocalPoint ( m_platformId , anchor ) ;
98
+ prismaticDef . maxMotorForce = 1000.0f ;
99
+ prismaticDef . motorSpeed = 0.0f ;
100
+ prismaticDef . enableMotor = true ;
101
+ prismaticDef . lowerTranslation = - 10.0f ;
102
+ prismaticDef . upperTranslation = 10.0f ;
103
+ prismaticDef . enableLimit = true ;
104
+
105
+ b2CreatePrismaticJoint ( m_worldId , ref prismaticDef ) ;
106
+ }
107
+ }
108
+
109
+ public override void UpdateGui ( )
110
+ {
111
+ float fontSize = ImGui . GetFontSize ( ) ;
112
+ float height = 11.0f * fontSize ;
113
+ ImGui . SetNextWindowPos ( new Vector2 ( 0.5f * fontSize , m_camera . m_height - height - 2.0f * fontSize ) , ImGuiCond . Once ) ;
114
+ ImGui . SetNextWindowSize ( new Vector2 ( 9.0f * fontSize , height ) ) ;
115
+ ImGui . Begin ( "Crash 01" , ImGuiWindowFlags . NoMove | ImGuiWindowFlags . NoResize ) ;
116
+
117
+ if ( ImGui . RadioButton ( "Static" , m_type == B2BodyType . b2_staticBody ) )
118
+ {
119
+ m_type = B2BodyType . b2_staticBody ;
120
+ b2Body_SetType ( m_platformId , B2BodyType . b2_staticBody ) ;
121
+ }
122
+
123
+ if ( ImGui . RadioButton ( "Kinematic" , m_type == B2BodyType . b2_kinematicBody ) )
124
+ {
125
+ m_type = B2BodyType . b2_kinematicBody ;
126
+ b2Body_SetType ( m_platformId , B2BodyType . b2_kinematicBody ) ;
127
+ b2Body_SetLinearVelocity ( m_platformId , new B2Vec2 ( - 0.1f , 0.0f ) ) ;
128
+ }
129
+
130
+ if ( ImGui . RadioButton ( "Dynamic" , m_type == B2BodyType . b2_dynamicBody ) )
131
+ {
132
+ m_type = B2BodyType . b2_dynamicBody ;
133
+ b2Body_SetType ( m_platformId , B2BodyType . b2_dynamicBody ) ;
134
+ }
135
+
136
+ if ( ImGui . Checkbox ( "Enable" , ref m_isEnabled ) )
137
+ {
138
+ if ( m_isEnabled )
139
+ {
140
+ b2Body_Enable ( m_attachmentId ) ;
141
+ }
142
+ else
143
+ {
144
+ b2Body_Disable ( m_attachmentId ) ;
145
+ }
146
+ }
147
+
148
+ ImGui . End ( ) ;
149
+ }
150
+ }
0 commit comments