-
Notifications
You must be signed in to change notification settings - Fork 20
/
Rigidbody.cs
154 lines (130 loc) · 4.3 KB
/
Rigidbody.cs
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
using UnityEngine;
using System.Collections;
namespace Sample07
{
/// <summary>
/// 刚体。表示了一个物体的运动属性
/// </summary>
public class Rigidbody
{
public int id;
/// 位移
public Vector2 position;
/// 移动速度
public Vector2 velocity;
/// 质量
public float mass;
/// 质量的倒数。方便除法计算,对于静态物体,可以认为质量无限大,invMass=0,所有作用力相乘结果都是0。
public float invMass;
/// 持续作用力。持续影响移动速度
public Vector2 force;
/// 脉冲力。仅影响移动速度一次
public Vector2 forceImpulse;
/// 旋转角度
public float rotation;
/// 角速度。单位是度,计算作用力的时候,切记要转换成弧度。
public float angleVelocity;
/// 角动量。相当于旋转质量
public float inertial;
/// 角动量倒数。方便除法计算
public float invInertial;
/// 扭矩力。持续的影响旋转速度
public float torque;
/// 扭矩脉冲力。仅影响旋转速度一次
public float torqueImpulse;
/// 摩擦力
public float fraction = 0.3f;
public Vector2 scale = Vector2.one;
/// 坐标变换矩阵。用来变换形状的坐标点。
public Matrix2D matrix;
public Shape shape;
public Physics physics;
public Entity entity;
public bool isStatic { get { return invMass == 0; } }
public Rigidbody(float mass, float inertial)
{
setMass(mass);
setInertial(inertial);
}
public void setMass(float m)
{
mass = m;
if (m >= float.PositiveInfinity)
{
invMass = 0;
}
else
{
invMass = 1.0f / m;
}
}
public void setInertial(float i)
{
inertial = i;
if (i >= float.PositiveInfinity)
{
invInertial = 0;
}
else
{
invInertial = 1.0f / i;
}
}
public void preUpdate(float dt)
{
// 计算作用力. v += a * t; a = F / m
velocity += force * invMass * dt;
angleVelocity += torque * invInertial * dt;
// 计算脉冲力
velocity += forceImpulse * invMass;
angleVelocity += torqueImpulse * invInertial;
forceImpulse = Vector2.zero;
torqueImpulse = 0;
// 计算速度衰减
velocity *= 1.0f - physics.damping * dt;
angleVelocity *= 1.0f - physics.damping * dt;
}
public void postUpdate(float dt)
{
position += velocity * dt;
rotation += angleVelocity * dt;
updateTransform();
}
public void updateTransform()
{
matrix.setTransform(position, rotation, scale);
shape.updateTransform();
}
/// 获得点关于法线方向的动量
public float getPointMoment(Vector2 point, Vector2 normal)
{
Vector2 r = point - position;
float rn = Vector2.Dot(r, normal);
return invMass + invInertial * (r.sqrMagnitude - rn * rn);
}
/// 获得点的速度
public Vector2 getPointVelocity(Vector2 point)
{
// 点的旋转速度为:每秒转过的弧度L = (angle / 360) * 2 PI * R。
// 点的旋转方向为:r的切线方向
Vector2 r = point - position;
return velocity + new Vector2(-r.y, r.x) * angleVelocity * Mathf.Deg2Rad;
}
public void applyImpulse(Vector2 force)
{
velocity += force * invMass;
}
public void applyTorqueImpulse(Vector2 point, Vector2 torque)
{
Vector2 radius = point - position;
angleVelocity += GJKTool.cross(radius, torque) * Mathf.Rad2Deg * invInertial;
}
public void sleep()
{
velocity.Set(0, 0);
angleVelocity = 0;
force.Set(0, 0);
forceImpulse.Set(0, 0);
}
}
}