-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsketch.js
230 lines (192 loc) · 4.75 KB
/
sketch.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
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
/*
*
1. how to deal with exits?
2. where to provide entry points for customization?
3. positional audio?
*
*
*
*
*/
let all = {};
let p5l;
let groundTexture;
function preload() {
groundTexture = loadImage("./aerial_grass_rock_diff_1k.jpg");
}
function setup() {
createCanvas(800, 600, WEBGL);
// Create and set up our camera
cam = createCamera();
// Tell p5 to use this camera
setCamera(cam);
// Setting "perspective matrix"
// 4x4 matrix of numbers - position, rotation, - shift from 3d to 2d
// field of view, aspect ratio, camera near (plane), camera (far)
cam.perspective(PI / 3.0, width / height, 0.1, 50000);
// position in 3d space
cam.setPosition(0, -1, 0);
strokeWeight(0.2);
let constraints = {
audio: true,
video: true,
};
myVideo = createCapture(constraints, function (stream) {
p5l = new p5LiveMedia(this, "CAPTURE", stream, "Shared Space");
p5l.on("stream", gotStream);
p5l.on("disconnect", gotDisconnect);
p5l.on("data", gotData);
});
myVideo.elt.muted = true;
myVideo.hide();
// add a debug grid so we can tell where we are
// debugMode(GRID, 25, 25, 0, 0, 0);
}
function draw() {
background(220, 230, 250);
lights();
addGround();
cameraControls();
for (const id in all) {
all[id].draw();
}
if (frameCount % 10 === 0){
sendStats();
}
}
/*
* This function adds a ground plane to the scene with a repeating texture on it!
*/
function addGround() {
// have to push and pop
push();
// box has height of 1 so 1/2 of that
rotateX(Math.PI / 2);
scale(50, 50, 50);
// we are using the vertex() function here instead of plane(),
// such that we can manually adjust the UV coordinates for a
// repeating texture. For more info, see this example:
// https://github.com/processing/p5.js/issues/2189
textureWrap(REPEAT);
texture(groundTexture);
let u = 2048,
v = 2048;
beginShape(TRIANGLES);
vertex(-1, -1, 0, 0, 0);
vertex(1, -1, 0, u, 0);
vertex(1, 1, 0, u, v);
vertex(1, 1, 0, u, v);
vertex(-1, 1, 0, 0, v);
vertex(-1, -1, 0, 0, 0);
endShape();
pop();
}
/*
* This function controls the movement of the camera in the space according to keypresses
*/
function cameraControls() {
// out controls
let leftRightMove = 0,
upDownMove = 0,
forwardBackwardMove = 0;
if (keyIsDown(87)) {
forwardBackwardMove = -0.1;
}
if (keyIsDown(83)) {
forwardBackwardMove = 0.1;
}
if (keyIsDown(65)) {
leftRightMove = -0.1;
}
if (keyIsDown(68)) {
leftRightMove = 0.1;
}
// move the camera along its local axes
cam.move(leftRightMove, 0, forwardBackwardMove);
cam.eyeY = -1.5;
// cam.pan(leftRightMove);
}
/*
* This function sends our current position and rotation to the other players in the space
*/
function sendStats(){
let cameraPosition = {
x: cam.eyeX, // There is no x, y, z
y: cam.eyeY,
z: cam.eyeZ,
};
let cameraLookAtPoint = {
x: cam.centerX,
y: cam.centerY,
z: cam.centerZ
}
let stats = {
position: cameraPosition,
lookAt: cameraLookAtPoint
}
if (p5l) {
p5l.send(JSON.stringify(stats));
}
}
// We got a new stream!
function gotStream(stream, id) {
stream.hide();
all[id] = new Avatar(stream, 0, 0, 0);
}
/*
* This function controls the rotation of the camera in the space when dragging the mouse
*/
function mouseDragged() {
let scaleFactor = 0.01;
let deltaX = pmouseX - mouseX;
let deltaY = pmouseY - mouseY;
cam.pan(deltaX * scaleFactor);
cam.tilt(-deltaY * scaleFactor);
}
/*
* This function deals with incoming position and rotation from other players
*/
function gotData(data, id) {
let stats = JSON.parse(data);
let position = stats.position;
let lookAt = stats.lookAt;
all[id].updatePos(position.x, position.y, position.z);
all[id].lookAt(lookAt.x,lookAt.y,lookAt.z);
}
function gotDisconnect(id) {
delete all[id];
}
/*
* This class sets up an 'avatar' representation of another player in space
*/
class Avatar {
constructor(vid, x, y, z) {
this.updatePos(x, y, z);
this.vid = vid;
this.heading = 0;
}
updatePos(x, y, z) {
this.x = x;
this.y = y;
this.z = z;
}
// see example here: https://p5js.org/reference/#/p5.Vector/sub
lookAt(x,y,z){
let lookAt = createVector(x,z);
let position = createVector(this.x,this.z);
let differenceVec = p5.Vector.sub(lookAt, position);
this.heading = -1 * differenceVec.heading();
}
draw() {
push();
translate(this.x, this.y, this.z);
// needs a rotate - something we have to send through
// adding Math.PI/2 (90 degrees) is a hack to ensure that we see
// the face rotated right-side up
// (seems the UVs of the box are not always right-side up)
rotateY(this.heading + Math.PI/2);
texture(this.vid);
box(1, 1, 1);
pop();
}
}