-
Notifications
You must be signed in to change notification settings - Fork 0
/
cone-wall-generator.js
70 lines (45 loc) · 2.19 KB
/
cone-wall-generator.js
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
import colors from 'colors';
import vector from './vector.js';
export function getWall(settings) {
let wall = {};
const wall_width = settings.three_dee.wall_diameter;
const wall_width_top = settings.three_dee.wall_top_diameter;
const wall_height = settings.three_dee.wall_height;
const wall_height_vector = vector(0, 0, wall_height);
const wall_position = vector(0,0,0)
.add(settings.three_dee.wall_offset)
wall.worldPosAtTextureCoord = (x,y) => {
let rotation = x;
let t = 0.5 + y;
let normal = vector(1,0,0)
.rotatedAroundZ(Math.PI * 2 * rotation + Math.PI * 2 * settings.three_dee.wall_roll_scalar, vector(0,0,0))
.normalized()
var pos = wall_position.add(normal.scale(wall_width * 0.5 * (1-t) + wall_width_top * 0.5 * t))
.add(wall_height_vector.scale(t))
return pos;
}
wall.worldNormalAtTextureCoord = (x, y) => {
// sample points counter clockwise as seen from direction opposing the normal
// and figure out the normal from that
const sample_dist = 0.001;
const a = wall.worldPosAtTextureCoord(x,y - sample_dist);
const b = wall.worldPosAtTextureCoord(x - sample_dist / 2, y + sample_dist / 2);
const c = wall.worldPosAtTextureCoord(x + sample_dist / 2, y + sample_dist / 2);
// find the normal of the face
const dir = b.sub(a).cross( c.sub(a) );
const normal = dir.normalized();
return normal;
}
wall.textureCoordAtWorldPos = (pos) => {
/*const heightVector = vector(0, wall_height, 0)
.rotatedAroundY(Math.PI * 2 * settings.three_dee.wall_rotation_scalar, vector(0, 0, 0));*/
// project the position onto the height vector
let y = wall_height_vector.normalized().dot(pos) / wall_height_vector.mag();
let normal = wall.worldNormalAtTextureCoord(0, 0);
let middle_to_pos = pos.sub(wall_position.add(wall_height_vector.scale(y))); // vector from closest point on center axis to pos
let angle = middle_to_pos.angleBetweenInXYPlane(normal);
let x = angle / Math.PI / 2; // convert angle to -0.5 to 0.5
return {x,y};
}
return wall;
}