Skip to content

Commit 85b98f5

Browse files
committed
Generalized 3d ngon creation
1 parent e5b2ad7 commit 85b98f5

2 files changed

Lines changed: 82 additions & 42 deletions

File tree

src/main.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { mat4, vec3 } from "./math/types";
22
import { perspective, identity, look_at, rotate, translate } from "./math/transformations";
3-
import { create_sphere } from "./rendering/utils/primitives";
3+
import { create_3d_ngon, create_antiprism, create_sphere, create_torus } from "./rendering/utils/primitives";
44
import { build_mesh, render_scene } from "./rendering/render";
55
import { StringBuffer } from "./utils/string_buffer";
66
import { Mesh } from "./rendering/types/mesh";
@@ -52,7 +52,7 @@ export function main_3d() {
5252

5353
const RESOLUTION = 32;
5454

55-
const sun_geo = create_sphere(1.5, RESOLUTION, RESOLUTION);
55+
const sun_geo = create_antiprism(RESOLUTION,1,1)
5656
const planet_geo = create_sphere(0.5, RESOLUTION/2, RESOLUTION/2);
5757
const bulb_geo = create_sphere(0.15, 8, 8);
5858

src/rendering/utils/primitives.ts

Lines changed: 80 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -100,47 +100,44 @@ export function create_flat_ngon(n:number, side_length:number, axis:vec3 | null
100100

101101
export function create_3d_ngon(
102102
n: number,
103-
side_length: number,
104-
depth_length: number | null,
105-
axis: vec3 | null = null,
106-
angle: number | null = null,
107-
translate_vec: vec3 | null = null
103+
width: number,
104+
height: number | null = null,
108105
): Geometry {
109-
if (n <= 2) {
110-
console.warn("Invalid n - There are no polygons of dimension 2 or less.");
111-
throw new Error("Cannot create a polygon with less than 3 sides.");
112-
}
113-
let depth = side_length;
114-
if(depth_length)
115-
depth = depth_length;
106+
return create_fustrum(n,width,width,height? height: width);
107+
}
116108

117-
const vertice_count = 2 + (2 * n);
118-
119-
const triangle_count = n * 4;
109+
export function create_fustrum(
110+
n:number,
111+
bottom_radius:number,
112+
top_radius:number,
113+
height:number
114+
): Geometry{
115+
const vertice_count = 2 + (2 * n);
116+
const triangle_count = n * 4;
120117

121118
const vertices = new ArrayType(vertice_count * 3);
122119
const indices = new IndexingType(triangle_count * 3);
123120

124-
const radius = side_length / (2 * Math.sin(Math.PI / n));
125121
const theta_step = (Math.PI * 2) / n;
122+
const h2 = height / 2;
126123

127-
vertices[0] = 0; vertices[1] = 0; vertices[2] = -depth / 2;
128-
vertices[3] = 0; vertices[4] = 0; vertices[5] = depth / 2;
124+
vertices[0] = 0; vertices[1] = 0; vertices[2] = -h2;
125+
vertices[3] = 0; vertices[4] = 0; vertices[5] = h2;
129126

130127
let vert_i = 6;
131128

132129
for (let i = 0; i < n; i++) {
133130
const theta = theta_step * i;
134-
vertices[vert_i++] = Math.cos(theta) * radius;
135-
vertices[vert_i++] = Math.sin(theta) * radius;
136-
vertices[vert_i++] = -depth / 2;
131+
vertices[vert_i++] = Math.cos(theta) * bottom_radius;
132+
vertices[vert_i++] = Math.sin(theta) * bottom_radius;
133+
vertices[vert_i++] = -h2;
137134
}
138135

139136
for (let i = 0; i < n; i++) {
140137
const theta = theta_step * i;
141-
vertices[vert_i++] = Math.cos(theta) * radius;
142-
vertices[vert_i++] = Math.sin(theta) * radius;
143-
vertices[vert_i++] = depth / 2;
138+
vertices[vert_i++] = Math.cos(theta) * top_radius;
139+
vertices[vert_i++] = Math.sin(theta) * top_radius;
140+
vertices[vert_i++] = h2;
144141
}
145142

146143
let ind_i = 0;
@@ -152,40 +149,83 @@ export function create_3d_ngon(
152149
const top_next = 2 + n + ((i + 1) % n);
153150

154151
indices[ind_i++] = 0;
155-
indices[ind_i++] = bottom_next;
156152
indices[ind_i++] = bottom_current;
153+
indices[ind_i++] = bottom_next;
157154

158155
indices[ind_i++] = 1;
159-
indices[ind_i++] = top_current;
160156
indices[ind_i++] = top_next;
157+
indices[ind_i++] = top_current;
161158

162159
indices[ind_i++] = bottom_current;
163-
indices[ind_i++] = bottom_next;
164160
indices[ind_i++] = top_current;
161+
indices[ind_i++] = bottom_next;
165162

166163
indices[ind_i++] = bottom_next;
167-
indices[ind_i++] = top_next;
168164
indices[ind_i++] = top_current;
165+
indices[ind_i++] = top_next;
169166
}
167+
return new Geometry(vertices, indices);
168+
}
170169

171-
let transform: mat4 = identity();
172170

173-
if (angle && axis) transform = rotate(transform, angle, axis);
174-
if (translate_vec) transform = translate(transform, translate_vec);
171+
export function create_antiprism(
172+
n: number,
173+
radius: number,
174+
height: number,
175+
): Geometry {
176+
if (n < 3) throw new Error("n must be at least 3.");
175177

176-
let vert = vec3(0, 0, 0);
177-
let out = vec4(0, 0, 0, 0);
178-
for (let i = 0; i < vertices.length; i += 3) {
179-
vert[0] = vertices[i]; vert[1] = vertices[i + 1]; vert[2] = vertices[i + 2];
180-
transform_vertex_mutate(transform, vert, out);
181-
vertices[i] = out[0]; vertices[i + 1] = out[1]; vertices[i + 2] = out[2];
178+
const vertice_count = 2 + (2 * n);
179+
const vertices = new ArrayType(vertice_count * 3);
180+
181+
const indices = new IndexingType((n + n + 2 * n) * 3);
182+
183+
const theta_step = (Math.PI * 2) / n;
184+
const half_step = theta_step / 2;
185+
const h2 = height / 2;
186+
187+
vertices[0] = 0; vertices[1] = 0; vertices[2] = -h2;
188+
vertices[3] = 0; vertices[4] = 0; vertices[5] = h2;
189+
190+
for (let i = 0; i < n; i++) {
191+
const theta = i * theta_step;
192+
193+
vertices[(2 + i) * 3 + 0] = Math.cos(theta) * radius;
194+
vertices[(2 + i) * 3 + 1] = Math.sin(theta) * radius;
195+
vertices[(2 + i) * 3 + 2] = -h2;
196+
197+
vertices[(2 + n + i) * 3 + 0] = Math.cos(theta + half_step) * radius;
198+
vertices[(2 + n + i) * 3 + 1] = Math.sin(theta + half_step) * radius;
199+
vertices[(2 + n + i) * 3 + 2] = h2;
182200
}
183201

202+
let ii = 0;
203+
for (let i = 0; i < n; i++) {
204+
const b_curr = 2 + i;
205+
const b_next = 2 + ((i + 1) % n);
206+
const t_curr = 2 + n + i;
207+
const t_next = 2 + n + ((i + 1) % n);
208+
209+
indices[ii++] = 0;
210+
indices[ii++] = b_curr;
211+
indices[ii++] = b_next;
212+
213+
indices[ii++] = 1;
214+
indices[ii++] = t_next;
215+
indices[ii++] = t_curr;
216+
217+
indices[ii++] = b_curr;
218+
indices[ii++] = t_curr;
219+
indices[ii++] = b_next;
220+
221+
indices[ii++] = b_next;
222+
indices[ii++] = t_curr;
223+
indices[ii++] = t_next;
224+
}
184225
return new Geometry(vertices, indices);
185226
}
186227

187228

188-
189229
export function create_torus(
190230
inner_radius: number,
191231
outer_radius: number,
@@ -226,12 +266,12 @@ export function create_torus(
226266
const second = first + slices + 1;
227267

228268
indices[ind_i++] = first;
229-
indices[ind_i++] = second;
230269
indices[ind_i++] = first + 1;
270+
indices[ind_i++] = second;
231271

232272
indices[ind_i++] = second;
233-
indices[ind_i++] = second + 1;
234273
indices[ind_i++] = first + 1;
274+
indices[ind_i++] = second + 1;
235275
}
236276
}
237277

0 commit comments

Comments
 (0)