-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbody.cpp
More file actions
144 lines (122 loc) · 5.29 KB
/
body.cpp
File metadata and controls
144 lines (122 loc) · 5.29 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
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
#include <stdio.h>
#include <cmath>
#include "sdl_compat.h"
#include "object.h"
#include "body.h"
#include "physics_world.h"
Body::Body(float x, float y, float width, float height, GameColor color)
:Object(x, y, width, height), color(color){
density = (100 + rand() % 100) / 100.0;
gravityStrength = 0.0f;
isGravityWell = false;
// Random rotation
rotation = (rand() % 3600) / 3600.0f * 2.0f * M_PI;
// Generate jagged edge — each vertex gets a unique radius multiplier
for (int i = 0; i < NUM_EDGE_VERTS; i++) {
float jitter = (rand() % 100) / 100.0f;
edgeRadii[i] = 0.85f + jitter * 0.2f;
}
// Smooth the edge
float smoothed[NUM_EDGE_VERTS];
for (int i = 0; i < NUM_EDGE_VERTS; i++) {
int prev = (i + NUM_EDGE_VERTS - 1) % NUM_EDGE_VERTS;
int next = (i + 1) % NUM_EDGE_VERTS;
smoothed[i] = edgeRadii[prev] * 0.25f + edgeRadii[i] * 0.5f + edgeRadii[next] * 0.25f;
}
for (int i = 0; i < NUM_EDGE_VERTS; i++) edgeRadii[i] = smoothed[i];
// Generate craters — unique per body
float avg_r = (width + height) / 4.0f;
int num_craters = 2 + rand() % 5;
for (int i = 0; i < num_craters; i++) {
Crater c;
c.angle = (rand() % 3600) / 3600.0f * 2.0f * M_PI;
c.dist = 0.15f + (rand() % 60) / 100.0f;
c.radius = avg_r * (0.06f + (rand() % 12) / 100.0f);
craters.push_back(c);
}
}
Body::~Body() {
}
void Body::initPhysics(PhysicsWorld& world) {
float avg_radius = (width2 + height2) / 2.0f;
physicsBody = world.createCircleBody(this, PhysicsBodyType::STATIC, avg_radius, 0.0f, 0.3f, 0.1f);
}
void Body::draw(void){
if (isGravityWell) {
float cx = pos.x;
float cy = pos.y;
float maxRadius = (width2 + height2) / 2;
// Accretion disk glow
GameColor diskGlow = {color.r * 0.3f, color.g * 0.2f, color.b * 0.5f, 0.06f};
draw_filled_ellipse(cx, cy, maxRadius * 1.5f, maxRadius * 1.5f, diskGlow);
for (int i = 5; i >= 1; i--) {
float radius = maxRadius * (i / 5.0f);
float t = i / 5.0f;
GameColor ringColor = map_rgb(
(int)(100 + 80 * t),
(int)(20 + 30 * t),
(int)(180 + 75 * t)
);
draw_ellipse(cx, cy, radius, radius, ringColor, 2.0f + i);
}
GameColor coreColor = map_rgb(50, 0, 100);
draw_filled_ellipse(cx, cy, maxRadius * 0.2f, maxRadius * 0.2f, coreColor);
} else {
float cx = pos.x;
float cy = pos.y;
float rx = width2;
float ry = height2;
// Atmosphere glow
GameColor atmo = {color.r, color.g, color.b, 0.08f};
draw_filled_ellipse(cx, cy, rx * 1.2f, ry * 1.2f, atmo);
// Draw jagged body as filled triangle fan (rotated)
float cosR = cosf(rotation), sinR = sinf(rotation);
for (int i = 0; i < NUM_EDGE_VERTS; i++) {
int next = (i + 1) % NUM_EDGE_VERTS;
float a1 = i * 2.0f * M_PI / NUM_EDGE_VERTS;
float a2 = next * 2.0f * M_PI / NUM_EDGE_VERTS;
// Local coords
float lx1 = cosf(a1) * rx * edgeRadii[i];
float ly1 = sinf(a1) * ry * edgeRadii[i];
float lx2 = cosf(a2) * rx * edgeRadii[next];
float ly2 = sinf(a2) * ry * edgeRadii[next];
// Rotate
float x1 = cx + lx1 * cosR - ly1 * sinR;
float y1 = cy + lx1 * sinR + ly1 * cosR;
float x2 = cx + lx2 * cosR - ly2 * sinR;
float y2 = cy + lx2 * sinR + ly2 * cosR;
draw_filled_triangle(cx, cy, x1, y1, x2, y2, color);
}
// Draw craters (rotated with the body)
GameColor craterColor = {color.r * 0.4f, color.g * 0.4f, color.b * 0.4f, 0.5f};
GameColor craterRim = {color.r * 0.8f, color.g * 0.8f, color.b * 0.8f, 0.3f};
for (auto& c : craters) {
float lx = cosf(c.angle) * rx * c.dist;
float ly = sinf(c.angle) * ry * c.dist;
float cr_x = cx + lx * cosR - ly * sinR;
float cr_y = cy + lx * sinR + ly * cosR;
draw_filled_ellipse(cr_x, cr_y, c.radius * 1.2f, c.radius * 1.2f, craterRim);
draw_filled_ellipse(cr_x, cr_y, c.radius, c.radius, craterColor);
}
// Highlight (light from upper-left, doesn't rotate)
GameColor highlight = {1.0f, 1.0f, 1.0f, 0.08f};
draw_filled_ellipse(cx - rx * 0.2f, cy - ry * 0.2f,
rx * 0.45f, ry * 0.45f, highlight);
// Jagged outline (rotated)
GameColor outline = {color.r * 0.4f, color.g * 0.4f, color.b * 0.4f, 0.7f};
for (int i = 0; i < NUM_EDGE_VERTS; i++) {
int next = (i + 1) % NUM_EDGE_VERTS;
float a1 = i * 2.0f * M_PI / NUM_EDGE_VERTS;
float a2 = next * 2.0f * M_PI / NUM_EDGE_VERTS;
float lx1 = cosf(a1) * rx * edgeRadii[i];
float ly1 = sinf(a1) * ry * edgeRadii[i];
float lx2 = cosf(a2) * rx * edgeRadii[next];
float ly2 = sinf(a2) * ry * edgeRadii[next];
float x1 = cx + lx1 * cosR - ly1 * sinR;
float y1 = cy + lx1 * sinR + ly1 * cosR;
float x2 = cx + lx2 * cosR - ly2 * sinR;
float y2 = cy + lx2 * sinR + ly2 * cosR;
draw_line(x1, y1, x2, y2, outline, 1.5f);
}
}
}