Skip to content

Commit e5b2ad7

Browse files
committed
Added new primitives
1 parent beaa0ba commit e5b2ad7

4 files changed

Lines changed: 218 additions & 9 deletions

File tree

index.html

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,8 @@
4242
stroke-width ="0.01"
4343
id="model-preview-container"
4444
shape-rendering ="optimizeSpeed"
45-
>
46-
</svg>
47-
45+
>
4846

47+
</svg>
4948
</body>
5049
</html>

src/main.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { Light } from "./rendering/types/light";
1212
import { parse_obj } from "./utils/parser";
1313
import type { Geometry } from "./rendering/types/geometry";
1414

15-
let uploaded_geometry:Geometry|null = null;
1615

1716
function generate_random_lights(LIGHT_COUNT:number, scene:Scene){
1817
const lights = [];
@@ -40,7 +39,6 @@ function generate_random_lights(LIGHT_COUNT:number, scene:Scene){
4039

4140
let animation_id:number|null = null;
4241

43-
4442
const frame_max = 1000;
4543
let frame_count = 0;
4644

@@ -52,8 +50,10 @@ export function main_3d() {
5250
if (!target) return;
5351
const wireframe_el = document.getElementById('wireframe-mode') as HTMLInputElement;
5452

55-
const sun_geo = create_sphere(1.5, 32, 32);
56-
const planet_geo = create_sphere(0.5, 16, 16);
53+
const RESOLUTION = 32;
54+
55+
const sun_geo = create_sphere(1.5, RESOLUTION, RESOLUTION);
56+
const planet_geo = create_sphere(0.5, RESOLUTION/2, RESOLUTION/2);
5757
const bulb_geo = create_sphere(0.15, 8, 8);
5858

5959
const scene: Scene = new Scene(sun_geo.indices.length + planet_geo.indices.length + bulb_geo.indices.length*32);
@@ -207,7 +207,7 @@ const preview_loop = () => {
207207

208208
render_scene(scene, [mul_mat4(vp, model_matrix)], true);
209209

210-
target.innerHTML = build_scene(scene, true, string_buffer);
210+
target.innerHTML = build_scene(scene, false, string_buffer);
211211
preview_animation_id = requestAnimationFrame(preview_loop);
212212
};
213213

src/rendering/types/node.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type { mat4 } from "../../math/types";
2+
import type { Mesh } from "./mesh";
3+
4+
class Node{
5+
mesh:Mesh;
6+
model:mat4;
7+
mvp:mat4;
8+
9+
constructor(mesh:Mesh, model:mat4, mvp:mat4){
10+
this.mesh = mesh;
11+
this.model = model;
12+
this.mvp = mvp;
13+
}
14+
}

src/rendering/utils/primitives.ts

Lines changed: 197 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import { ArrayType, IndexingType } from "../../math/types";
1+
import { identity, rotate, translate } from "../../math/transformations";
2+
import { ArrayType, IndexingType, mat4, vec3, vec4 } from "../../math/types";
3+
import { transform_vertex_mutate } from "../clip_space/vertex";
24
import { Geometry } from "../types/geometry";
35

46
export function create_sphere(radius: number, rings: number, slices: number):Geometry {
@@ -41,4 +43,198 @@ export function create_sphere(radius: number, rings: number, slices: number):Geo
4143
}
4244
}
4345
return new Geometry(vertices,indices);
46+
}
47+
48+
49+
export function create_flat_ngon(n:number, side_length:number, axis:vec3 | null = null, angle:number | null = null, translate_vec:vec3 | null =null) : Geometry{
50+
if(n<=2){
51+
console.warn("Invalid n - There are no polygons of dimension 2 or less.");
52+
throw new Error("Cannot create a polygon with less than 3 sides.");
53+
}
54+
55+
const vertice_count = n + 1;
56+
const triangle_count = n * 3;
57+
58+
const vertices = new ArrayType(vertice_count * 3);
59+
const indices = new IndexingType(triangle_count);
60+
61+
vertices[0] = 0;
62+
vertices[1] = 0;
63+
vertices[2] = 0;
64+
65+
const radius = side_length / (2 * Math.sin(Math.PI / n));
66+
const theta_step = (Math.PI * 2) / n
67+
68+
let vert_i = 3;
69+
70+
for(let i = 0; i < n; ++i){
71+
const theta = theta_step * i;
72+
vertices[vert_i++] = Math.cos(theta) * radius;
73+
vertices[vert_i++] = Math.sin(theta) * radius;
74+
vertices[vert_i++] = 0;
75+
}
76+
77+
let ind_i = 0;
78+
79+
for(let i = 1; i <= n; ++i){
80+
indices[ind_i++] = 0;
81+
indices[ind_i++] = i;
82+
indices[ind_i++] = (i === n) ? 1 : i + 1;
83+
}
84+
let transform:mat4 = identity();
85+
86+
if(angle && axis)
87+
transform = rotate(transform,angle,axis);
88+
if(translate_vec)
89+
transform = translate(transform,translate_vec);
90+
91+
let vert = vec3(0,0,0);
92+
let out = vec4(0,0,0,0);
93+
for(let i = 0; i < vertices.length; i+=3){
94+
vert[0] = vertices[i]; vert[1] = vertices[i+1]; vert[2] = vertices[i+2];
95+
transform_vertex_mutate(transform,vert,out);
96+
vertices[i] = out[0]; vertices[i + 1] = out[1]; vertices[i + 2] = out[2];
97+
}
98+
return new Geometry(vertices,indices);
99+
}
100+
101+
export function create_3d_ngon(
102+
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
108+
): 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;
116+
117+
const vertice_count = 2 + (2 * n);
118+
119+
const triangle_count = n * 4;
120+
121+
const vertices = new ArrayType(vertice_count * 3);
122+
const indices = new IndexingType(triangle_count * 3);
123+
124+
const radius = side_length / (2 * Math.sin(Math.PI / n));
125+
const theta_step = (Math.PI * 2) / n;
126+
127+
vertices[0] = 0; vertices[1] = 0; vertices[2] = -depth / 2;
128+
vertices[3] = 0; vertices[4] = 0; vertices[5] = depth / 2;
129+
130+
let vert_i = 6;
131+
132+
for (let i = 0; i < n; i++) {
133+
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;
137+
}
138+
139+
for (let i = 0; i < n; i++) {
140+
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;
144+
}
145+
146+
let ind_i = 0;
147+
148+
for (let i = 0; i < n; i++) {
149+
const bottom_current = 2 + i;
150+
const bottom_next = 2 + ((i + 1) % n);
151+
const top_current = 2 + n + i;
152+
const top_next = 2 + n + ((i + 1) % n);
153+
154+
indices[ind_i++] = 0;
155+
indices[ind_i++] = bottom_next;
156+
indices[ind_i++] = bottom_current;
157+
158+
indices[ind_i++] = 1;
159+
indices[ind_i++] = top_current;
160+
indices[ind_i++] = top_next;
161+
162+
indices[ind_i++] = bottom_current;
163+
indices[ind_i++] = bottom_next;
164+
indices[ind_i++] = top_current;
165+
166+
indices[ind_i++] = bottom_next;
167+
indices[ind_i++] = top_next;
168+
indices[ind_i++] = top_current;
169+
}
170+
171+
let transform: mat4 = identity();
172+
173+
if (angle && axis) transform = rotate(transform, angle, axis);
174+
if (translate_vec) transform = translate(transform, translate_vec);
175+
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];
182+
}
183+
184+
return new Geometry(vertices, indices);
185+
}
186+
187+
188+
189+
export function create_torus(
190+
inner_radius: number,
191+
outer_radius: number,
192+
rings: number,
193+
slices: number,
194+
): Geometry {
195+
const vertice_count = (rings + 1) * (slices + 1) * 3;
196+
const vertices = new ArrayType(vertice_count);
197+
198+
const indices = new IndexingType(rings * slices * 6);
199+
200+
let vert_i = 0;
201+
let ind_i = 0;
202+
203+
for (let ring = 0; ring <= rings; ring++) {
204+
const phi = (ring * 2 * Math.PI) / rings;
205+
const sinPhi = Math.sin(phi);
206+
const cosPhi = Math.cos(phi);
207+
208+
for (let slice = 0; slice <= slices; slice++) {
209+
const theta = (slice * 2 * Math.PI) / slices;
210+
const sinTheta = Math.sin(theta);
211+
const cosTheta = Math.cos(theta);
212+
213+
const x = (outer_radius + inner_radius * cosPhi) * cosTheta;
214+
const y = inner_radius * sinPhi;
215+
const z = (outer_radius + inner_radius * cosPhi) * sinTheta;
216+
217+
vertices[vert_i++] = x;
218+
vertices[vert_i++] = y;
219+
vertices[vert_i++] = z;
220+
}
221+
}
222+
223+
for (let ring = 0; ring < rings; ring++) {
224+
for (let slice = 0; slice < slices; slice++) {
225+
const first = (ring * (slices + 1)) + slice;
226+
const second = first + slices + 1;
227+
228+
indices[ind_i++] = first;
229+
indices[ind_i++] = second;
230+
indices[ind_i++] = first + 1;
231+
232+
indices[ind_i++] = second;
233+
indices[ind_i++] = second + 1;
234+
indices[ind_i++] = first + 1;
235+
}
236+
}
237+
238+
239+
return new Geometry(vertices, indices);
44240
}

0 commit comments

Comments
 (0)