techkaczynski.dev / code

summaryrefslogtreecommitdiff
path: root/physics.h
blob: 5a9a8d0877056c211ede385f803e3b835d55ff79 (plain)
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
155
156
157
158
#ifndef PHYSICS_H
#define PHYSICS_H

#include "common.h"

typedef enum {
	PHYS_SHAPE_BOX,
	PHYS_SHAPE_SPHERE,
	PHYS_SHAPE_CAPSULE,
	PHYS_SHAPE_CYLINDER,
	PHYS_SHAPE_CONVEX_HULL,
	PHYS_SHAPE_STATIC_TRIMESH,
} PhysicsShapeTag;

typedef enum {
	PHYS_JOINT_SPHERICAL,
	PHYS_JOINT_REVOLUTE,
	PHYS_JOINT_PRISMATIC,
	PHYS_JOINT_WELD,
	PHYS_JOINT_WHEEL,
	PHYS_JOINT_DISTANCE,
} PhysicsJointTag;

typedef enum {
	PHYS_JOINT_LIMIT,
	PHYS_JOINT_SPRING,
	PHYS_JOINT_MOTOR,
} PhysicsJointFlags;

typedef enum {
	PHYS_MODE_STATIC,
	PHYS_MODE_KINEMATIC,
	PHYS_MODE_DYNAMIC,
} PhysicsMode;

typedef enum {
	PHYS_MASK_DEFAULT,
	PHYS_MASK_WORLD,
	PHYS_MASK_PROP,
	PHYS_MASK_PLAYER,
	PHYS_MASK_PARTICLE,

	PHYS_MASK_EDITOR_SELECTABLE,
	PHYS_MASK_EDITOR_RAYCAST,
} PhysicsMask;

typedef struct {
	PhysicsShapeTag tag;
	union {
		struct {
			Vec3 sz;
		} Box;

		struct {
			f32 radius;
		} Sphere;

		struct {
			f32 height, radius;
		} Capsule, Cylinder;

		struct {
			Vec3 *points;
			u32 point_cnt;
		} ConvexHull;

		struct {
			Vec3 *points;
			u32 *indices;
			u32 point_cnt, idx_cnt;
		} TriMesh;
	};

	/* local to body */
	Vec3 pos;
	Quaternion rot;

	f32 density, friction, restitution;
	Flags32 category_bits, mask_bits;
} PhysicsShape;

typedef struct {
	PhysicsShape *shapes;
	u32 shape_cnt;

	/* local to entity */
	Vec3 pos;
	Quaternion rot;

	f32 linear_damping, angular_damping;
	f32 gravity_scale;
	PhysicsMode mode;
	bool enable_sleep;
} PhysicsBody;

/*
	physics joint fields meaning changes depending on their context.

	anchor_a/frame_rot_a define the joint frame local to body_a.
	anchor_b/frame_rot_b define the joint frame local to body_b.
	frame rotations are normalized quaternions.

	lower/upper are generic limits
	- revolute: radians
	- prismatic: metres
	- distance: metres
	- wheel: suspension travel

	springs:
	- spring_hz: frequency of the spring response; higher = stiffer/faster
	- spring_damping: damping ratio; controls oscillation

	motors:
		revolute:
		motor_speed = angular velocity
		motor_force = maximum torque

		prismatic:
		motor_speed = linear velocity
		motor_force = maximum force

		wheel:
		motor_speed = wheel angular velocity
		motor_force = maximum drive/braking torque
*/
typedef struct {
	PhysicsJointTag tag;
	u32 body_a, body_b;
	Flags32 flags;

	Vec3 anchor_a, anchor_b;
	Quaternion frame_rot_a, frame_rot_b;
	// Vec3 axis_a, axis_b;

	f32 lower, upper;
	f32 spring_hz, spring_damping;
	f32 motor_speed, motor_force;
} PhysicsJoint;

typedef struct {
	u64 entity_id;
	b3BodyId id;
	b3ShapeId *shapes; // count is stored in PhysicsCmp
} PhysicsBodyRuntime;

typedef struct {
	b3WorldDef world_def;
	b3WorldId world_id;
	bool simulate;
} PhysicsInfo;

extern PhysicsInfo physics;

void 		physics_init(void);
void 		physics_exit(void);
void 		physics_update(void);

#endif