-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathDonut.cs
More file actions
106 lines (85 loc) · 3.31 KB
/
Donut.cs
File metadata and controls
106 lines (85 loc) · 3.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// SPDX-FileCopyrightText: 2023 Erin Catto
// SPDX-FileCopyrightText: 2025 Ikpil Choi(ikpil@naver.com)
// SPDX-License-Identifier: MIT
using System;
using static Box2D.NET.B2Joints;
using static Box2D.NET.B2Ids;
using static Box2D.NET.B2Types;
using static Box2D.NET.B2MathFunction;
using static Box2D.NET.B2Bodies;
using static Box2D.NET.B2Shapes;
using static Box2D.NET.B2Diagnostics;
namespace Box2D.NET.Samples.Samples;
public struct Donut
{
public const int m_sides = 7;
private B2FixedArray7<B2BodyId> m_bodyIds;
private B2FixedArray7<B2JointId> m_jointIds;
private bool m_isSpawned;
public Donut()
{
B2_ASSERT(m_sides == B2FixedArray7<B2BodyId>.Size);
B2_ASSERT(m_sides == B2FixedArray7<B2JointId>.Size);
}
public void Create(B2WorldId worldId, B2Vec2 position, float scale, int groupIndex, bool enableSensorEvents, B2UserData userData)
{
B2_ASSERT(m_isSpawned == false);
for (int i = 0; i < m_sides; ++i)
{
B2_ASSERT(B2_IS_NULL(m_bodyIds[i]));
B2_ASSERT(B2_IS_NULL(m_jointIds[i]));
}
float radius = 1.0f * scale;
float deltaAngle = 2.0f * B2_PI / m_sides;
float length = 2.0f * B2_PI * radius / m_sides;
B2Capsule capsule = new B2Capsule(new B2Vec2(0.0f, -0.5f * length), new B2Vec2(0.0f, 0.5f * length), 0.25f * scale);
B2Vec2 center = position;
B2BodyDef bodyDef = b2DefaultBodyDef();
bodyDef.type = B2BodyType.b2_dynamicBody;
bodyDef.userData = userData;
B2ShapeDef shapeDef = b2DefaultShapeDef();
shapeDef.enableSensorEvents = enableSensorEvents;
shapeDef.filter.groupIndex = -groupIndex;
shapeDef.material.friction = 0.3f;
// Create bodies
float angle = 0.0f;
for (int i = 0; i < m_sides; ++i)
{
bodyDef.position = new B2Vec2(radius * MathF.Cos(angle) + center.X, radius * MathF.Sin(angle) + center.Y);
bodyDef.rotation = b2MakeRot(angle);
m_bodyIds[i] = b2CreateBody(worldId, bodyDef);
b2CreateCapsuleShape(m_bodyIds[i], shapeDef, capsule);
angle += deltaAngle;
}
// Create joints
B2WeldJointDef weldDef = b2DefaultWeldJointDef();
weldDef.angularHertz = 5.0f;
weldDef.angularDampingRatio = 0.0f;
weldDef.@base.localFrameA.p = new B2Vec2(0.0f, 0.5f * length);
weldDef.@base.localFrameB.p = new B2Vec2(0.0f, -0.5f * length);
weldDef.@base.drawScale = 0.5f * scale;
B2BodyId prevBodyId = m_bodyIds[m_sides - 1];
for (int i = 0; i < m_sides; ++i)
{
weldDef.@base.bodyIdA = prevBodyId;
weldDef.@base.bodyIdB = m_bodyIds[i];
B2Rot qA = b2Body_GetRotation(prevBodyId);
B2Rot qB = b2Body_GetRotation(m_bodyIds[i]);
weldDef.@base.localFrameA.q = b2InvMulRot(qA, qB);
m_jointIds[i] = b2CreateWeldJoint(worldId, weldDef);
prevBodyId = weldDef.@base.bodyIdB;
}
m_isSpawned = true;
}
public void Destroy()
{
B2_ASSERT(m_isSpawned == true);
for (int i = 0; i < m_sides; ++i)
{
b2DestroyBody(m_bodyIds[i]);
m_bodyIds[i] = b2_nullBodyId;
m_jointIds[i] = b2_nullJointId;
}
m_isSpawned = false;
}
}