Files
nothoughts/node_modules/pixi.js/lib/scene/mesh-simple/RopeGeometry.js
2025-08-04 18:57:35 +02:00

152 lines
4.3 KiB
JavaScript

'use strict';
var MeshGeometry = require('../mesh/shared/MeshGeometry.js');
"use strict";
const _RopeGeometry = class _RopeGeometry extends MeshGeometry.MeshGeometry {
/**
* @param options - Options to be applied to rope geometry
*/
constructor(options) {
const { width, points, textureScale } = { ..._RopeGeometry.defaultOptions, ...options };
super({
positions: new Float32Array(points.length * 4),
uvs: new Float32Array(points.length * 4),
indices: new Uint32Array((points.length - 1) * 6)
});
this.points = points;
this._width = width;
this.textureScale = textureScale;
this._build();
}
/**
* The width (i.e., thickness) of the rope.
* @readonly
*/
get width() {
return this._width;
}
/** Refreshes Rope indices and uvs */
_build() {
const points = this.points;
if (!points)
return;
const vertexBuffer = this.getBuffer("aPosition");
const uvBuffer = this.getBuffer("aUV");
const indexBuffer = this.getIndex();
if (points.length < 1) {
return;
}
if (vertexBuffer.data.length / 4 !== points.length) {
vertexBuffer.data = new Float32Array(points.length * 4);
uvBuffer.data = new Float32Array(points.length * 4);
indexBuffer.data = new Uint16Array((points.length - 1) * 6);
}
const uvs = uvBuffer.data;
const indices = indexBuffer.data;
uvs[0] = 0;
uvs[1] = 0;
uvs[2] = 0;
uvs[3] = 1;
let amount = 0;
let prev = points[0];
const textureWidth = this._width * this.textureScale;
const total = points.length;
for (let i = 0; i < total; i++) {
const index = i * 4;
if (this.textureScale > 0) {
const dx = prev.x - points[i].x;
const dy = prev.y - points[i].y;
const distance = Math.sqrt(dx * dx + dy * dy);
prev = points[i];
amount += distance / textureWidth;
} else {
amount = i / (total - 1);
}
uvs[index] = amount;
uvs[index + 1] = 0;
uvs[index + 2] = amount;
uvs[index + 3] = 1;
}
let indexCount = 0;
for (let i = 0; i < total - 1; i++) {
const index = i * 2;
indices[indexCount++] = index;
indices[indexCount++] = index + 1;
indices[indexCount++] = index + 2;
indices[indexCount++] = index + 2;
indices[indexCount++] = index + 1;
indices[indexCount++] = index + 3;
}
uvBuffer.update();
indexBuffer.update();
this.updateVertices();
}
/** refreshes vertices of Rope mesh */
updateVertices() {
const points = this.points;
if (points.length < 1) {
return;
}
let lastPoint = points[0];
let nextPoint;
let perpX = 0;
let perpY = 0;
const vertices = this.buffers[0].data;
const total = points.length;
const halfWidth = this.textureScale > 0 ? this.textureScale * this._width / 2 : this._width / 2;
for (let i = 0; i < total; i++) {
const point = points[i];
const index = i * 4;
if (i < points.length - 1) {
nextPoint = points[i + 1];
} else {
nextPoint = point;
}
perpY = -(nextPoint.x - lastPoint.x);
perpX = nextPoint.y - lastPoint.y;
let ratio = (1 - i / (total - 1)) * 10;
if (ratio > 1) {
ratio = 1;
}
const perpLength = Math.sqrt(perpX * perpX + perpY * perpY);
if (perpLength < 1e-6) {
perpX = 0;
perpY = 0;
} else {
perpX /= perpLength;
perpY /= perpLength;
perpX *= halfWidth;
perpY *= halfWidth;
}
vertices[index] = point.x + perpX;
vertices[index + 1] = point.y + perpY;
vertices[index + 2] = point.x - perpX;
vertices[index + 3] = point.y - perpY;
lastPoint = point;
}
this.buffers[0].update();
}
/** Refreshes Rope indices and uvs */
update() {
if (this.textureScale > 0) {
this._build();
} else {
this.updateVertices();
}
}
};
/** Default options for RopeGeometry constructor. */
_RopeGeometry.defaultOptions = {
/** The width (i.e., thickness) of the rope. */
width: 200,
/** An array of points that determine the rope. */
points: [],
/** Rope texture scale, if zero then the rope texture is stretched. */
textureScale: 0
};
let RopeGeometry = _RopeGeometry;
exports.RopeGeometry = RopeGeometry;
//# sourceMappingURL=RopeGeometry.js.map