Skip to content

Commit 2641218

Browse files
committed
Merge branch 'dev-2.0' into 2.0-modules
2 parents 468ab53 + acb5ac4 commit 2641218

File tree

29 files changed

+5524
-5181
lines changed

29 files changed

+5524
-5181
lines changed

src/app.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ import data from './data';
2929
data(p5);
3030

3131
// DOM
32-
import dom from './dom/dom';
33-
dom(p5, p5.prototype);
32+
import dom from './dom';
33+
dom(p5);
3434

3535
// events
3636
import events from './events';

src/core/environment.js

+146-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
import * as C from './constants';
10+
import { Vector } from '../math/p5.Vector';
1011

1112
function environment(p5, fn){
1213
const standardCursors = [C.ARROW, C.CROSS, C.HAND, C.MOVE, C.TEXT, C.WAIT];
@@ -1261,10 +1262,154 @@ function environment(p5, fn){
12611262
}
12621263
return v;
12631264
};
1265+
1266+
/**
1267+
* Converts 3D world coordinates to 2D screen coordinates.
1268+
*
1269+
* This function takes a 3D vector and converts its coordinates
1270+
* from the world space to screen space. This can be useful for placing
1271+
* 2D elements in a 3D scene or for determining the screen position
1272+
* of 3D objects.
1273+
*
1274+
* @method worldToScreen
1275+
* @param {p5.Vector} worldPosition The 3D coordinates in the world space.
1276+
* @return {p5.Vector} A vector containing the 2D screen coordinates.
1277+
* @example
1278+
* <div>
1279+
* <code>
1280+
*
1281+
* function setup() {
1282+
* createCanvas(150, 150);
1283+
* let vertices = [
1284+
* createVector(-20, -20),
1285+
* createVector(20, -20),
1286+
* createVector(20, 20),
1287+
* createVector(-20, 20)
1288+
* ];
1289+
*
1290+
* push();
1291+
* translate(75, 55);
1292+
* rotate(PI / 4);
1293+
*
1294+
* // Convert world coordinates to screen coordinates
1295+
* let screenPos = vertices.map(v => worldToScreen(v));
1296+
* pop();
1297+
*
1298+
* background(200);
1299+
*
1300+
* stroke(0);
1301+
* fill(100, 150, 255, 100);
1302+
* beginShape();
1303+
* screenPos.forEach(pos => vertex(pos.x, pos.y));
1304+
* endShape(CLOSE);
1305+
*
1306+
* screenPos.forEach((pos, i) => {
1307+
* fill(0);
1308+
* textSize(10);
1309+
* if (i === 0) {
1310+
* text(i + 1, pos.x + 3, pos.y - 7);
1311+
* } else if (i === 1) {
1312+
* text(i + 1, pos.x + 7, pos.y + 2);
1313+
* } else if (i === 2) {
1314+
* text(i + 1, pos.x - 2, pos.y + 12);
1315+
* } else if (i === 3) {
1316+
* text(i + 1, pos.x - 12, pos.y - 2);
1317+
* }
1318+
* });
1319+
*
1320+
* fill(0);
1321+
* noStroke();
1322+
* textSize(10);
1323+
* let legendY = height - 35;
1324+
* screenPos.forEach((pos, i) => {
1325+
* text(`Vertex ${i + 1}: (${pos.x.toFixed(1)}, ${pos.y.toFixed(1)})`, 5, legendY + i * 10);
1326+
* });
1327+
*
1328+
* describe('A rotating square is transformed and drawn using screen coordinates.');
1329+
*
1330+
* }
1331+
* </code>
1332+
* </div>
1333+
*
1334+
* @example
1335+
* <div>
1336+
* <code>
1337+
* let vertices;
1338+
*
1339+
* function setup() {
1340+
* createCanvas(100, 100, WEBGL);
1341+
* vertices = [
1342+
* createVector(-25, -25, -25),
1343+
* createVector(25, -25, -25),
1344+
* createVector(25, 25, -25),
1345+
* createVector(-25, 25, -25),
1346+
* createVector(-25, -25, 25),
1347+
* createVector(25, -25, 25),
1348+
* createVector(25, 25, 25),
1349+
* createVector(-25, 25, 25)
1350+
* ];
1351+
*
1352+
* describe('A rotating cube with points mapped to 2D screen space and displayed as ellipses.');
1353+
*
1354+
* }
1355+
*
1356+
* function draw() {
1357+
* background(200);
1358+
*
1359+
* // Animate rotation
1360+
* let rotationX = millis() / 1000;
1361+
* let rotationY = millis() / 1200;
1362+
*
1363+
* push();
1364+
*
1365+
* rotateX(rotationX);
1366+
* rotateY(rotationY);
1367+
*
1368+
* // Convert world coordinates to screen coordinates
1369+
* let screenPos = vertices.map(v => worldToScreen(v));
1370+
*
1371+
* pop();
1372+
*
1373+
* screenPos.forEach((pos, i) => {
1374+
*
1375+
* let screenX = pos.x - width / 2;
1376+
* let screenY = pos.y - height / 2;
1377+
* fill(0);
1378+
* noStroke();
1379+
* ellipse(screenX, screenY, 3, 3);
1380+
* });
1381+
* }
1382+
* </code>
1383+
* </div>
1384+
*
1385+
*/
1386+
fn.worldToScreen = function(worldPosition) {
1387+
const renderer = this._renderer;
1388+
if (renderer.drawingContext instanceof CanvasRenderingContext2D) {
1389+
// Handle 2D context
1390+
const transformMatrix = new DOMMatrix()
1391+
.scale(1 / renderer._pInst.pixelDensity())
1392+
.multiply(renderer.drawingContext.getTransform());
1393+
const screenCoordinates = transformMatrix.transformPoint(
1394+
new DOMPoint(worldPosition.x, worldPosition.y)
1395+
);
1396+
return new p5.Vector(screenCoordinates.x, screenCoordinates.y);
1397+
} else {
1398+
// Handle WebGL context (3D)
1399+
const modelViewMatrix = renderer.calculateCombinedMatrix();
1400+
const cameraCoordinates = modelViewMatrix.multiplyPoint(worldPosition);
1401+
const normalizedDeviceCoordinates =
1402+
renderer.states.uPMatrix.multiplyAndNormalizePoint(cameraCoordinates);
1403+
const screenX = (0.5 + 0.5 * normalizedDeviceCoordinates.x) * this.width;
1404+
const screenY = (0.5 - 0.5 * normalizedDeviceCoordinates.y) * this.height;
1405+
const screenZ = 0.5 + 0.5 * normalizedDeviceCoordinates.z;
1406+
return new Vector(screenX, screenY, screenZ);
1407+
}
1408+
};
12641409
}
12651410

12661411
export default environment;
12671412

12681413
if(typeof p5 !== 'undefined'){
12691414
environment(p5, p5.prototype);
1270-
}
1415+
}

src/core/p5.Renderer2D.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Renderer } from './p5.Renderer';
44
import { Element } from './p5.Element';
55
import { Graphics } from './p5.Graphics';
66
import { Image } from '../image/p5.Image';
7-
import { MediaElement } from '../dom/dom';
7+
import { MediaElement } from '../dom/media_element';
88

99
const styleEmpty = 'rgba(0,0,0,0)';
1010
// const alphaThreshold = 0.00125; // minimum visible

0 commit comments

Comments
 (0)