Initial project import
This commit is contained in:
296
node_modules/three-stdlib/misc/ConvexObjectBreaker.cjs
generated
vendored
Normal file
296
node_modules/three-stdlib/misc/ConvexObjectBreaker.cjs
generated
vendored
Normal file
@@ -0,0 +1,296 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
||||
const THREE = require("three");
|
||||
const ConvexGeometry = require("../geometries/ConvexGeometry.cjs");
|
||||
const _v1 = /* @__PURE__ */ new THREE.Vector3();
|
||||
const ConvexObjectBreaker = /* @__PURE__ */ (() => {
|
||||
class ConvexObjectBreaker2 {
|
||||
constructor(minSizeForBreak = 1.4, smallDelta = 1e-4) {
|
||||
this.minSizeForBreak = minSizeForBreak;
|
||||
this.smallDelta = smallDelta;
|
||||
this.tempLine1 = new THREE.Line3();
|
||||
this.tempPlane1 = new THREE.Plane();
|
||||
this.tempPlane2 = new THREE.Plane();
|
||||
this.tempPlane_Cut = new THREE.Plane();
|
||||
this.tempCM1 = new THREE.Vector3();
|
||||
this.tempCM2 = new THREE.Vector3();
|
||||
this.tempVector3 = new THREE.Vector3();
|
||||
this.tempVector3_2 = new THREE.Vector3();
|
||||
this.tempVector3_3 = new THREE.Vector3();
|
||||
this.tempVector3_P0 = new THREE.Vector3();
|
||||
this.tempVector3_P1 = new THREE.Vector3();
|
||||
this.tempVector3_P2 = new THREE.Vector3();
|
||||
this.tempVector3_N0 = new THREE.Vector3();
|
||||
this.tempVector3_N1 = new THREE.Vector3();
|
||||
this.tempVector3_AB = new THREE.Vector3();
|
||||
this.tempVector3_CB = new THREE.Vector3();
|
||||
this.tempResultObjects = { object1: null, object2: null };
|
||||
this.segments = [];
|
||||
const n = 30 * 30;
|
||||
for (let i = 0; i < n; i++)
|
||||
this.segments[i] = false;
|
||||
}
|
||||
prepareBreakableObject(object, mass, velocity, angularVelocity, breakable) {
|
||||
const userData = object.userData;
|
||||
userData.mass = mass;
|
||||
userData.velocity = velocity.clone();
|
||||
userData.angularVelocity = angularVelocity.clone();
|
||||
userData.breakable = breakable;
|
||||
}
|
||||
/*
|
||||
* @param {int} maxRadialIterations Iterations for radial cuts.
|
||||
* @param {int} maxRandomIterations Max random iterations for not-radial cuts
|
||||
*
|
||||
* Returns the array of pieces
|
||||
*/
|
||||
subdivideByImpact(object, pointOfImpact, normal, maxRadialIterations, maxRandomIterations) {
|
||||
const debris = [];
|
||||
const tempPlane1 = this.tempPlane1;
|
||||
const tempPlane2 = this.tempPlane2;
|
||||
this.tempVector3.addVectors(pointOfImpact, normal);
|
||||
tempPlane1.setFromCoplanarPoints(pointOfImpact, object.position, this.tempVector3);
|
||||
const maxTotalIterations = maxRandomIterations + maxRadialIterations;
|
||||
const scope = this;
|
||||
function subdivideRadial(subObject, startAngle, endAngle, numIterations) {
|
||||
if (Math.random() < numIterations * 0.05 || numIterations > maxTotalIterations) {
|
||||
debris.push(subObject);
|
||||
return;
|
||||
}
|
||||
let angle = Math.PI;
|
||||
if (numIterations === 0) {
|
||||
tempPlane2.normal.copy(tempPlane1.normal);
|
||||
tempPlane2.constant = tempPlane1.constant;
|
||||
} else {
|
||||
if (numIterations <= maxRadialIterations) {
|
||||
angle = (endAngle - startAngle) * (0.2 + 0.6 * Math.random()) + startAngle;
|
||||
scope.tempVector3_2.copy(object.position).sub(pointOfImpact).applyAxisAngle(normal, angle).add(pointOfImpact);
|
||||
tempPlane2.setFromCoplanarPoints(pointOfImpact, scope.tempVector3, scope.tempVector3_2);
|
||||
} else {
|
||||
angle = (0.5 * (numIterations & 1) + 0.2 * (2 - Math.random())) * Math.PI;
|
||||
scope.tempVector3_2.copy(pointOfImpact).sub(subObject.position).applyAxisAngle(normal, angle).add(subObject.position);
|
||||
scope.tempVector3_3.copy(normal).add(subObject.position);
|
||||
tempPlane2.setFromCoplanarPoints(subObject.position, scope.tempVector3_3, scope.tempVector3_2);
|
||||
}
|
||||
}
|
||||
scope.cutByPlane(subObject, tempPlane2, scope.tempResultObjects);
|
||||
const obj1 = scope.tempResultObjects.object1;
|
||||
const obj2 = scope.tempResultObjects.object2;
|
||||
if (obj1) {
|
||||
subdivideRadial(obj1, startAngle, angle, numIterations + 1);
|
||||
}
|
||||
if (obj2) {
|
||||
subdivideRadial(obj2, angle, endAngle, numIterations + 1);
|
||||
}
|
||||
}
|
||||
subdivideRadial(object, 0, 2 * Math.PI, 0);
|
||||
return debris;
|
||||
}
|
||||
cutByPlane(object, plane, output) {
|
||||
const geometry = object.geometry;
|
||||
const coords = geometry.attributes.position.array;
|
||||
const normals = geometry.attributes.normal.array;
|
||||
const numPoints = coords.length / 3;
|
||||
let numFaces = numPoints / 3;
|
||||
let indices = geometry.getIndex();
|
||||
if (indices) {
|
||||
indices = indices.array;
|
||||
numFaces = indices.length / 3;
|
||||
}
|
||||
function getVertexIndex(faceIdx, vert) {
|
||||
const idx = faceIdx * 3 + vert;
|
||||
return indices ? indices[idx] : idx;
|
||||
}
|
||||
const points1 = [];
|
||||
const points2 = [];
|
||||
const delta = this.smallDelta;
|
||||
const numPointPairs = numPoints * numPoints;
|
||||
for (let i = 0; i < numPointPairs; i++)
|
||||
this.segments[i] = false;
|
||||
const p0 = this.tempVector3_P0;
|
||||
const p1 = this.tempVector3_P1;
|
||||
const n0 = this.tempVector3_N0;
|
||||
const n1 = this.tempVector3_N1;
|
||||
for (let i = 0; i < numFaces - 1; i++) {
|
||||
const a1 = getVertexIndex(i, 0);
|
||||
const b1 = getVertexIndex(i, 1);
|
||||
const c1 = getVertexIndex(i, 2);
|
||||
n0.set(normals[a1], normals[a1] + 1, normals[a1] + 2);
|
||||
for (let j = i + 1; j < numFaces; j++) {
|
||||
const a2 = getVertexIndex(j, 0);
|
||||
const b2 = getVertexIndex(j, 1);
|
||||
const c2 = getVertexIndex(j, 2);
|
||||
n1.set(normals[a2], normals[a2] + 1, normals[a2] + 2);
|
||||
const coplanar = 1 - n0.dot(n1) < delta;
|
||||
if (coplanar) {
|
||||
if (a1 === a2 || a1 === b2 || a1 === c2) {
|
||||
if (b1 === a2 || b1 === b2 || b1 === c2) {
|
||||
this.segments[a1 * numPoints + b1] = true;
|
||||
this.segments[b1 * numPoints + a1] = true;
|
||||
} else {
|
||||
this.segments[c1 * numPoints + a1] = true;
|
||||
this.segments[a1 * numPoints + c1] = true;
|
||||
}
|
||||
} else if (b1 === a2 || b1 === b2 || b1 === c2) {
|
||||
this.segments[c1 * numPoints + b1] = true;
|
||||
this.segments[b1 * numPoints + c1] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const localPlane = this.tempPlane_Cut;
|
||||
object.updateMatrix();
|
||||
ConvexObjectBreaker2.transformPlaneToLocalSpace(plane, object.matrix, localPlane);
|
||||
for (let i = 0; i < numFaces; i++) {
|
||||
const va = getVertexIndex(i, 0);
|
||||
const vb = getVertexIndex(i, 1);
|
||||
const vc = getVertexIndex(i, 2);
|
||||
for (let segment = 0; segment < 3; segment++) {
|
||||
const i0 = segment === 0 ? va : segment === 1 ? vb : vc;
|
||||
const i1 = segment === 0 ? vb : segment === 1 ? vc : va;
|
||||
const segmentState = this.segments[i0 * numPoints + i1];
|
||||
if (segmentState)
|
||||
continue;
|
||||
this.segments[i0 * numPoints + i1] = true;
|
||||
this.segments[i1 * numPoints + i0] = true;
|
||||
p0.set(coords[3 * i0], coords[3 * i0 + 1], coords[3 * i0 + 2]);
|
||||
p1.set(coords[3 * i1], coords[3 * i1 + 1], coords[3 * i1 + 2]);
|
||||
let mark0 = 0;
|
||||
let d = localPlane.distanceToPoint(p0);
|
||||
if (d > delta) {
|
||||
mark0 = 2;
|
||||
points2.push(p0.clone());
|
||||
} else if (d < -delta) {
|
||||
mark0 = 1;
|
||||
points1.push(p0.clone());
|
||||
} else {
|
||||
mark0 = 3;
|
||||
points1.push(p0.clone());
|
||||
points2.push(p0.clone());
|
||||
}
|
||||
let mark1 = 0;
|
||||
d = localPlane.distanceToPoint(p1);
|
||||
if (d > delta) {
|
||||
mark1 = 2;
|
||||
points2.push(p1.clone());
|
||||
} else if (d < -delta) {
|
||||
mark1 = 1;
|
||||
points1.push(p1.clone());
|
||||
} else {
|
||||
mark1 = 3;
|
||||
points1.push(p1.clone());
|
||||
points2.push(p1.clone());
|
||||
}
|
||||
if (mark0 === 1 && mark1 === 2 || mark0 === 2 && mark1 === 1) {
|
||||
this.tempLine1.start.copy(p0);
|
||||
this.tempLine1.end.copy(p1);
|
||||
let intersection = new THREE.Vector3();
|
||||
intersection = localPlane.intersectLine(this.tempLine1, intersection);
|
||||
if (intersection === null) {
|
||||
console.error("Internal error: segment does not intersect plane.");
|
||||
output.segmentedObject1 = null;
|
||||
output.segmentedObject2 = null;
|
||||
return 0;
|
||||
}
|
||||
points1.push(intersection);
|
||||
points2.push(intersection.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
const newMass = object.userData.mass * 0.5;
|
||||
this.tempCM1.set(0, 0, 0);
|
||||
let radius1 = 0;
|
||||
const numPoints1 = points1.length;
|
||||
if (numPoints1 > 0) {
|
||||
for (let i = 0; i < numPoints1; i++)
|
||||
this.tempCM1.add(points1[i]);
|
||||
this.tempCM1.divideScalar(numPoints1);
|
||||
for (let i = 0; i < numPoints1; i++) {
|
||||
const p = points1[i];
|
||||
p.sub(this.tempCM1);
|
||||
radius1 = Math.max(radius1, p.x, p.y, p.z);
|
||||
}
|
||||
this.tempCM1.add(object.position);
|
||||
}
|
||||
this.tempCM2.set(0, 0, 0);
|
||||
let radius2 = 0;
|
||||
const numPoints2 = points2.length;
|
||||
if (numPoints2 > 0) {
|
||||
for (let i = 0; i < numPoints2; i++)
|
||||
this.tempCM2.add(points2[i]);
|
||||
this.tempCM2.divideScalar(numPoints2);
|
||||
for (let i = 0; i < numPoints2; i++) {
|
||||
const p = points2[i];
|
||||
p.sub(this.tempCM2);
|
||||
radius2 = Math.max(radius2, p.x, p.y, p.z);
|
||||
}
|
||||
this.tempCM2.add(object.position);
|
||||
}
|
||||
let object1 = null;
|
||||
let object2 = null;
|
||||
let numObjects = 0;
|
||||
if (numPoints1 > 4) {
|
||||
object1 = new THREE.Mesh(new ConvexGeometry.ConvexGeometry(points1), object.material);
|
||||
object1.position.copy(this.tempCM1);
|
||||
object1.quaternion.copy(object.quaternion);
|
||||
this.prepareBreakableObject(
|
||||
object1,
|
||||
newMass,
|
||||
object.userData.velocity,
|
||||
object.userData.angularVelocity,
|
||||
2 * radius1 > this.minSizeForBreak
|
||||
);
|
||||
numObjects++;
|
||||
}
|
||||
if (numPoints2 > 4) {
|
||||
object2 = new THREE.Mesh(new ConvexGeometry.ConvexGeometry(points2), object.material);
|
||||
object2.position.copy(this.tempCM2);
|
||||
object2.quaternion.copy(object.quaternion);
|
||||
this.prepareBreakableObject(
|
||||
object2,
|
||||
newMass,
|
||||
object.userData.velocity,
|
||||
object.userData.angularVelocity,
|
||||
2 * radius2 > this.minSizeForBreak
|
||||
);
|
||||
numObjects++;
|
||||
}
|
||||
output.object1 = object1;
|
||||
output.object2 = object2;
|
||||
return numObjects;
|
||||
}
|
||||
static transformFreeVector(v, m) {
|
||||
const x = v.x, y = v.y, z = v.z;
|
||||
const e = m.elements;
|
||||
v.x = e[0] * x + e[4] * y + e[8] * z;
|
||||
v.y = e[1] * x + e[5] * y + e[9] * z;
|
||||
v.z = e[2] * x + e[6] * y + e[10] * z;
|
||||
return v;
|
||||
}
|
||||
static transformFreeVectorInverse(v, m) {
|
||||
const x = v.x, y = v.y, z = v.z;
|
||||
const e = m.elements;
|
||||
v.x = e[0] * x + e[1] * y + e[2] * z;
|
||||
v.y = e[4] * x + e[5] * y + e[6] * z;
|
||||
v.z = e[8] * x + e[9] * y + e[10] * z;
|
||||
return v;
|
||||
}
|
||||
static transformTiedVectorInverse(v, m) {
|
||||
const x = v.x, y = v.y, z = v.z;
|
||||
const e = m.elements;
|
||||
v.x = e[0] * x + e[1] * y + e[2] * z - e[12];
|
||||
v.y = e[4] * x + e[5] * y + e[6] * z - e[13];
|
||||
v.z = e[8] * x + e[9] * y + e[10] * z - e[14];
|
||||
return v;
|
||||
}
|
||||
static transformPlaneToLocalSpace(plane, m, resultPlane) {
|
||||
resultPlane.normal.copy(plane.normal);
|
||||
resultPlane.constant = plane.constant;
|
||||
const referencePoint = ConvexObjectBreaker2.transformTiedVectorInverse(plane.coplanarPoint(_v1), m);
|
||||
ConvexObjectBreaker2.transformFreeVectorInverse(resultPlane.normal, m);
|
||||
resultPlane.constant = -referencePoint.dot(resultPlane.normal);
|
||||
}
|
||||
}
|
||||
return ConvexObjectBreaker2;
|
||||
})();
|
||||
exports.ConvexObjectBreaker = ConvexObjectBreaker;
|
||||
//# sourceMappingURL=ConvexObjectBreaker.cjs.map
|
||||
1
node_modules/three-stdlib/misc/ConvexObjectBreaker.cjs.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/ConvexObjectBreaker.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
25
node_modules/three-stdlib/misc/ConvexObjectBreaker.d.ts
generated
vendored
Normal file
25
node_modules/three-stdlib/misc/ConvexObjectBreaker.d.ts
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
import { Object3D, Plane, Vector3 } from 'three'
|
||||
|
||||
export interface CutByPlaneOutput {
|
||||
object1: Object3D
|
||||
object2: Object3D
|
||||
}
|
||||
|
||||
export class ConvexObjectBreaker {
|
||||
constructor(minSizeForBreak?: number, smallDelta?: number)
|
||||
prepareBreakableObject(
|
||||
object: Object3D,
|
||||
mass: number,
|
||||
velocity: Vector3,
|
||||
angularVelocity: Vector3,
|
||||
breakable: boolean,
|
||||
): void
|
||||
subdivideByImpact(
|
||||
object: Object3D,
|
||||
pointOfImpact: Vector3,
|
||||
normal: Vector3,
|
||||
maxRadialIterations: number,
|
||||
maxRandomIterations: number,
|
||||
): Object3D[]
|
||||
cutByPlane(object: Object3D, plane: Plane, output: CutByPlaneOutput): number
|
||||
}
|
||||
296
node_modules/three-stdlib/misc/ConvexObjectBreaker.js
generated
vendored
Normal file
296
node_modules/three-stdlib/misc/ConvexObjectBreaker.js
generated
vendored
Normal file
@@ -0,0 +1,296 @@
|
||||
import { Line3, Plane, Vector3, Mesh } from "three";
|
||||
import { ConvexGeometry } from "../geometries/ConvexGeometry.js";
|
||||
const _v1 = /* @__PURE__ */ new Vector3();
|
||||
const ConvexObjectBreaker = /* @__PURE__ */ (() => {
|
||||
class ConvexObjectBreaker2 {
|
||||
constructor(minSizeForBreak = 1.4, smallDelta = 1e-4) {
|
||||
this.minSizeForBreak = minSizeForBreak;
|
||||
this.smallDelta = smallDelta;
|
||||
this.tempLine1 = new Line3();
|
||||
this.tempPlane1 = new Plane();
|
||||
this.tempPlane2 = new Plane();
|
||||
this.tempPlane_Cut = new Plane();
|
||||
this.tempCM1 = new Vector3();
|
||||
this.tempCM2 = new Vector3();
|
||||
this.tempVector3 = new Vector3();
|
||||
this.tempVector3_2 = new Vector3();
|
||||
this.tempVector3_3 = new Vector3();
|
||||
this.tempVector3_P0 = new Vector3();
|
||||
this.tempVector3_P1 = new Vector3();
|
||||
this.tempVector3_P2 = new Vector3();
|
||||
this.tempVector3_N0 = new Vector3();
|
||||
this.tempVector3_N1 = new Vector3();
|
||||
this.tempVector3_AB = new Vector3();
|
||||
this.tempVector3_CB = new Vector3();
|
||||
this.tempResultObjects = { object1: null, object2: null };
|
||||
this.segments = [];
|
||||
const n = 30 * 30;
|
||||
for (let i = 0; i < n; i++)
|
||||
this.segments[i] = false;
|
||||
}
|
||||
prepareBreakableObject(object, mass, velocity, angularVelocity, breakable) {
|
||||
const userData = object.userData;
|
||||
userData.mass = mass;
|
||||
userData.velocity = velocity.clone();
|
||||
userData.angularVelocity = angularVelocity.clone();
|
||||
userData.breakable = breakable;
|
||||
}
|
||||
/*
|
||||
* @param {int} maxRadialIterations Iterations for radial cuts.
|
||||
* @param {int} maxRandomIterations Max random iterations for not-radial cuts
|
||||
*
|
||||
* Returns the array of pieces
|
||||
*/
|
||||
subdivideByImpact(object, pointOfImpact, normal, maxRadialIterations, maxRandomIterations) {
|
||||
const debris = [];
|
||||
const tempPlane1 = this.tempPlane1;
|
||||
const tempPlane2 = this.tempPlane2;
|
||||
this.tempVector3.addVectors(pointOfImpact, normal);
|
||||
tempPlane1.setFromCoplanarPoints(pointOfImpact, object.position, this.tempVector3);
|
||||
const maxTotalIterations = maxRandomIterations + maxRadialIterations;
|
||||
const scope = this;
|
||||
function subdivideRadial(subObject, startAngle, endAngle, numIterations) {
|
||||
if (Math.random() < numIterations * 0.05 || numIterations > maxTotalIterations) {
|
||||
debris.push(subObject);
|
||||
return;
|
||||
}
|
||||
let angle = Math.PI;
|
||||
if (numIterations === 0) {
|
||||
tempPlane2.normal.copy(tempPlane1.normal);
|
||||
tempPlane2.constant = tempPlane1.constant;
|
||||
} else {
|
||||
if (numIterations <= maxRadialIterations) {
|
||||
angle = (endAngle - startAngle) * (0.2 + 0.6 * Math.random()) + startAngle;
|
||||
scope.tempVector3_2.copy(object.position).sub(pointOfImpact).applyAxisAngle(normal, angle).add(pointOfImpact);
|
||||
tempPlane2.setFromCoplanarPoints(pointOfImpact, scope.tempVector3, scope.tempVector3_2);
|
||||
} else {
|
||||
angle = (0.5 * (numIterations & 1) + 0.2 * (2 - Math.random())) * Math.PI;
|
||||
scope.tempVector3_2.copy(pointOfImpact).sub(subObject.position).applyAxisAngle(normal, angle).add(subObject.position);
|
||||
scope.tempVector3_3.copy(normal).add(subObject.position);
|
||||
tempPlane2.setFromCoplanarPoints(subObject.position, scope.tempVector3_3, scope.tempVector3_2);
|
||||
}
|
||||
}
|
||||
scope.cutByPlane(subObject, tempPlane2, scope.tempResultObjects);
|
||||
const obj1 = scope.tempResultObjects.object1;
|
||||
const obj2 = scope.tempResultObjects.object2;
|
||||
if (obj1) {
|
||||
subdivideRadial(obj1, startAngle, angle, numIterations + 1);
|
||||
}
|
||||
if (obj2) {
|
||||
subdivideRadial(obj2, angle, endAngle, numIterations + 1);
|
||||
}
|
||||
}
|
||||
subdivideRadial(object, 0, 2 * Math.PI, 0);
|
||||
return debris;
|
||||
}
|
||||
cutByPlane(object, plane, output) {
|
||||
const geometry = object.geometry;
|
||||
const coords = geometry.attributes.position.array;
|
||||
const normals = geometry.attributes.normal.array;
|
||||
const numPoints = coords.length / 3;
|
||||
let numFaces = numPoints / 3;
|
||||
let indices = geometry.getIndex();
|
||||
if (indices) {
|
||||
indices = indices.array;
|
||||
numFaces = indices.length / 3;
|
||||
}
|
||||
function getVertexIndex(faceIdx, vert) {
|
||||
const idx = faceIdx * 3 + vert;
|
||||
return indices ? indices[idx] : idx;
|
||||
}
|
||||
const points1 = [];
|
||||
const points2 = [];
|
||||
const delta = this.smallDelta;
|
||||
const numPointPairs = numPoints * numPoints;
|
||||
for (let i = 0; i < numPointPairs; i++)
|
||||
this.segments[i] = false;
|
||||
const p0 = this.tempVector3_P0;
|
||||
const p1 = this.tempVector3_P1;
|
||||
const n0 = this.tempVector3_N0;
|
||||
const n1 = this.tempVector3_N1;
|
||||
for (let i = 0; i < numFaces - 1; i++) {
|
||||
const a1 = getVertexIndex(i, 0);
|
||||
const b1 = getVertexIndex(i, 1);
|
||||
const c1 = getVertexIndex(i, 2);
|
||||
n0.set(normals[a1], normals[a1] + 1, normals[a1] + 2);
|
||||
for (let j = i + 1; j < numFaces; j++) {
|
||||
const a2 = getVertexIndex(j, 0);
|
||||
const b2 = getVertexIndex(j, 1);
|
||||
const c2 = getVertexIndex(j, 2);
|
||||
n1.set(normals[a2], normals[a2] + 1, normals[a2] + 2);
|
||||
const coplanar = 1 - n0.dot(n1) < delta;
|
||||
if (coplanar) {
|
||||
if (a1 === a2 || a1 === b2 || a1 === c2) {
|
||||
if (b1 === a2 || b1 === b2 || b1 === c2) {
|
||||
this.segments[a1 * numPoints + b1] = true;
|
||||
this.segments[b1 * numPoints + a1] = true;
|
||||
} else {
|
||||
this.segments[c1 * numPoints + a1] = true;
|
||||
this.segments[a1 * numPoints + c1] = true;
|
||||
}
|
||||
} else if (b1 === a2 || b1 === b2 || b1 === c2) {
|
||||
this.segments[c1 * numPoints + b1] = true;
|
||||
this.segments[b1 * numPoints + c1] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const localPlane = this.tempPlane_Cut;
|
||||
object.updateMatrix();
|
||||
ConvexObjectBreaker2.transformPlaneToLocalSpace(plane, object.matrix, localPlane);
|
||||
for (let i = 0; i < numFaces; i++) {
|
||||
const va = getVertexIndex(i, 0);
|
||||
const vb = getVertexIndex(i, 1);
|
||||
const vc = getVertexIndex(i, 2);
|
||||
for (let segment = 0; segment < 3; segment++) {
|
||||
const i0 = segment === 0 ? va : segment === 1 ? vb : vc;
|
||||
const i1 = segment === 0 ? vb : segment === 1 ? vc : va;
|
||||
const segmentState = this.segments[i0 * numPoints + i1];
|
||||
if (segmentState)
|
||||
continue;
|
||||
this.segments[i0 * numPoints + i1] = true;
|
||||
this.segments[i1 * numPoints + i0] = true;
|
||||
p0.set(coords[3 * i0], coords[3 * i0 + 1], coords[3 * i0 + 2]);
|
||||
p1.set(coords[3 * i1], coords[3 * i1 + 1], coords[3 * i1 + 2]);
|
||||
let mark0 = 0;
|
||||
let d = localPlane.distanceToPoint(p0);
|
||||
if (d > delta) {
|
||||
mark0 = 2;
|
||||
points2.push(p0.clone());
|
||||
} else if (d < -delta) {
|
||||
mark0 = 1;
|
||||
points1.push(p0.clone());
|
||||
} else {
|
||||
mark0 = 3;
|
||||
points1.push(p0.clone());
|
||||
points2.push(p0.clone());
|
||||
}
|
||||
let mark1 = 0;
|
||||
d = localPlane.distanceToPoint(p1);
|
||||
if (d > delta) {
|
||||
mark1 = 2;
|
||||
points2.push(p1.clone());
|
||||
} else if (d < -delta) {
|
||||
mark1 = 1;
|
||||
points1.push(p1.clone());
|
||||
} else {
|
||||
mark1 = 3;
|
||||
points1.push(p1.clone());
|
||||
points2.push(p1.clone());
|
||||
}
|
||||
if (mark0 === 1 && mark1 === 2 || mark0 === 2 && mark1 === 1) {
|
||||
this.tempLine1.start.copy(p0);
|
||||
this.tempLine1.end.copy(p1);
|
||||
let intersection = new Vector3();
|
||||
intersection = localPlane.intersectLine(this.tempLine1, intersection);
|
||||
if (intersection === null) {
|
||||
console.error("Internal error: segment does not intersect plane.");
|
||||
output.segmentedObject1 = null;
|
||||
output.segmentedObject2 = null;
|
||||
return 0;
|
||||
}
|
||||
points1.push(intersection);
|
||||
points2.push(intersection.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
const newMass = object.userData.mass * 0.5;
|
||||
this.tempCM1.set(0, 0, 0);
|
||||
let radius1 = 0;
|
||||
const numPoints1 = points1.length;
|
||||
if (numPoints1 > 0) {
|
||||
for (let i = 0; i < numPoints1; i++)
|
||||
this.tempCM1.add(points1[i]);
|
||||
this.tempCM1.divideScalar(numPoints1);
|
||||
for (let i = 0; i < numPoints1; i++) {
|
||||
const p = points1[i];
|
||||
p.sub(this.tempCM1);
|
||||
radius1 = Math.max(radius1, p.x, p.y, p.z);
|
||||
}
|
||||
this.tempCM1.add(object.position);
|
||||
}
|
||||
this.tempCM2.set(0, 0, 0);
|
||||
let radius2 = 0;
|
||||
const numPoints2 = points2.length;
|
||||
if (numPoints2 > 0) {
|
||||
for (let i = 0; i < numPoints2; i++)
|
||||
this.tempCM2.add(points2[i]);
|
||||
this.tempCM2.divideScalar(numPoints2);
|
||||
for (let i = 0; i < numPoints2; i++) {
|
||||
const p = points2[i];
|
||||
p.sub(this.tempCM2);
|
||||
radius2 = Math.max(radius2, p.x, p.y, p.z);
|
||||
}
|
||||
this.tempCM2.add(object.position);
|
||||
}
|
||||
let object1 = null;
|
||||
let object2 = null;
|
||||
let numObjects = 0;
|
||||
if (numPoints1 > 4) {
|
||||
object1 = new Mesh(new ConvexGeometry(points1), object.material);
|
||||
object1.position.copy(this.tempCM1);
|
||||
object1.quaternion.copy(object.quaternion);
|
||||
this.prepareBreakableObject(
|
||||
object1,
|
||||
newMass,
|
||||
object.userData.velocity,
|
||||
object.userData.angularVelocity,
|
||||
2 * radius1 > this.minSizeForBreak
|
||||
);
|
||||
numObjects++;
|
||||
}
|
||||
if (numPoints2 > 4) {
|
||||
object2 = new Mesh(new ConvexGeometry(points2), object.material);
|
||||
object2.position.copy(this.tempCM2);
|
||||
object2.quaternion.copy(object.quaternion);
|
||||
this.prepareBreakableObject(
|
||||
object2,
|
||||
newMass,
|
||||
object.userData.velocity,
|
||||
object.userData.angularVelocity,
|
||||
2 * radius2 > this.minSizeForBreak
|
||||
);
|
||||
numObjects++;
|
||||
}
|
||||
output.object1 = object1;
|
||||
output.object2 = object2;
|
||||
return numObjects;
|
||||
}
|
||||
static transformFreeVector(v, m) {
|
||||
const x = v.x, y = v.y, z = v.z;
|
||||
const e = m.elements;
|
||||
v.x = e[0] * x + e[4] * y + e[8] * z;
|
||||
v.y = e[1] * x + e[5] * y + e[9] * z;
|
||||
v.z = e[2] * x + e[6] * y + e[10] * z;
|
||||
return v;
|
||||
}
|
||||
static transformFreeVectorInverse(v, m) {
|
||||
const x = v.x, y = v.y, z = v.z;
|
||||
const e = m.elements;
|
||||
v.x = e[0] * x + e[1] * y + e[2] * z;
|
||||
v.y = e[4] * x + e[5] * y + e[6] * z;
|
||||
v.z = e[8] * x + e[9] * y + e[10] * z;
|
||||
return v;
|
||||
}
|
||||
static transformTiedVectorInverse(v, m) {
|
||||
const x = v.x, y = v.y, z = v.z;
|
||||
const e = m.elements;
|
||||
v.x = e[0] * x + e[1] * y + e[2] * z - e[12];
|
||||
v.y = e[4] * x + e[5] * y + e[6] * z - e[13];
|
||||
v.z = e[8] * x + e[9] * y + e[10] * z - e[14];
|
||||
return v;
|
||||
}
|
||||
static transformPlaneToLocalSpace(plane, m, resultPlane) {
|
||||
resultPlane.normal.copy(plane.normal);
|
||||
resultPlane.constant = plane.constant;
|
||||
const referencePoint = ConvexObjectBreaker2.transformTiedVectorInverse(plane.coplanarPoint(_v1), m);
|
||||
ConvexObjectBreaker2.transformFreeVectorInverse(resultPlane.normal, m);
|
||||
resultPlane.constant = -referencePoint.dot(resultPlane.normal);
|
||||
}
|
||||
}
|
||||
return ConvexObjectBreaker2;
|
||||
})();
|
||||
export {
|
||||
ConvexObjectBreaker
|
||||
};
|
||||
//# sourceMappingURL=ConvexObjectBreaker.js.map
|
||||
1
node_modules/three-stdlib/misc/ConvexObjectBreaker.js.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/ConvexObjectBreaker.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
206
node_modules/three-stdlib/misc/GPUComputationRenderer.cjs
generated
vendored
Normal file
206
node_modules/three-stdlib/misc/GPUComputationRenderer.cjs
generated
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
||||
const THREE = require("three");
|
||||
class GPUComputationRenderer {
|
||||
constructor(sizeX, sizeY, renderer) {
|
||||
this.variables = [];
|
||||
this.currentTextureIndex = 0;
|
||||
let dataType = THREE.FloatType;
|
||||
const scene = new THREE.Scene();
|
||||
const camera = new THREE.Camera();
|
||||
camera.position.z = 1;
|
||||
const passThruUniforms = {
|
||||
passThruTexture: { value: null }
|
||||
};
|
||||
const passThruShader = createShaderMaterial(getPassThroughFragmentShader(), passThruUniforms);
|
||||
const mesh = new THREE.Mesh(new THREE.PlaneGeometry(2, 2), passThruShader);
|
||||
scene.add(mesh);
|
||||
this.setDataType = function(type) {
|
||||
dataType = type;
|
||||
return this;
|
||||
};
|
||||
this.addVariable = function(variableName, computeFragmentShader, initialValueTexture) {
|
||||
const material = this.createShaderMaterial(computeFragmentShader);
|
||||
const variable = {
|
||||
name: variableName,
|
||||
initialValueTexture,
|
||||
material,
|
||||
dependencies: null,
|
||||
renderTargets: [],
|
||||
wrapS: null,
|
||||
wrapT: null,
|
||||
minFilter: THREE.NearestFilter,
|
||||
magFilter: THREE.NearestFilter
|
||||
};
|
||||
this.variables.push(variable);
|
||||
return variable;
|
||||
};
|
||||
this.setVariableDependencies = function(variable, dependencies) {
|
||||
variable.dependencies = dependencies;
|
||||
};
|
||||
this.init = function() {
|
||||
if (renderer.capabilities.isWebGL2 === false && renderer.extensions.has("OES_texture_float") === false) {
|
||||
return "No OES_texture_float support for float textures.";
|
||||
}
|
||||
if (renderer.capabilities.maxVertexTextures === 0) {
|
||||
return "No support for vertex shader textures.";
|
||||
}
|
||||
for (let i = 0; i < this.variables.length; i++) {
|
||||
const variable = this.variables[i];
|
||||
variable.renderTargets[0] = this.createRenderTarget(
|
||||
sizeX,
|
||||
sizeY,
|
||||
variable.wrapS,
|
||||
variable.wrapT,
|
||||
variable.minFilter,
|
||||
variable.magFilter
|
||||
);
|
||||
variable.renderTargets[1] = this.createRenderTarget(
|
||||
sizeX,
|
||||
sizeY,
|
||||
variable.wrapS,
|
||||
variable.wrapT,
|
||||
variable.minFilter,
|
||||
variable.magFilter
|
||||
);
|
||||
this.renderTexture(variable.initialValueTexture, variable.renderTargets[0]);
|
||||
this.renderTexture(variable.initialValueTexture, variable.renderTargets[1]);
|
||||
const material = variable.material;
|
||||
const uniforms = material.uniforms;
|
||||
if (variable.dependencies !== null) {
|
||||
for (let d = 0; d < variable.dependencies.length; d++) {
|
||||
const depVar = variable.dependencies[d];
|
||||
if (depVar.name !== variable.name) {
|
||||
let found = false;
|
||||
for (let j = 0; j < this.variables.length; j++) {
|
||||
if (depVar.name === this.variables[j].name) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
return "Variable dependency not found. Variable=" + variable.name + ", dependency=" + depVar.name;
|
||||
}
|
||||
}
|
||||
uniforms[depVar.name] = { value: null };
|
||||
material.fragmentShader = "\nuniform sampler2D " + depVar.name + ";\n" + material.fragmentShader;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.currentTextureIndex = 0;
|
||||
return null;
|
||||
};
|
||||
this.compute = function() {
|
||||
const currentTextureIndex = this.currentTextureIndex;
|
||||
const nextTextureIndex = this.currentTextureIndex === 0 ? 1 : 0;
|
||||
for (let i = 0, il = this.variables.length; i < il; i++) {
|
||||
const variable = this.variables[i];
|
||||
if (variable.dependencies !== null) {
|
||||
const uniforms = variable.material.uniforms;
|
||||
for (let d = 0, dl = variable.dependencies.length; d < dl; d++) {
|
||||
const depVar = variable.dependencies[d];
|
||||
uniforms[depVar.name].value = depVar.renderTargets[currentTextureIndex].texture;
|
||||
}
|
||||
}
|
||||
this.doRenderTarget(variable.material, variable.renderTargets[nextTextureIndex]);
|
||||
}
|
||||
this.currentTextureIndex = nextTextureIndex;
|
||||
};
|
||||
this.getCurrentRenderTarget = function(variable) {
|
||||
return variable.renderTargets[this.currentTextureIndex];
|
||||
};
|
||||
this.getAlternateRenderTarget = function(variable) {
|
||||
return variable.renderTargets[this.currentTextureIndex === 0 ? 1 : 0];
|
||||
};
|
||||
this.dispose = function() {
|
||||
mesh.geometry.dispose();
|
||||
mesh.material.dispose();
|
||||
const variables = this.variables;
|
||||
for (let i = 0; i < variables.length; i++) {
|
||||
const variable = variables[i];
|
||||
if (variable.initialValueTexture)
|
||||
variable.initialValueTexture.dispose();
|
||||
const renderTargets = variable.renderTargets;
|
||||
for (let j = 0; j < renderTargets.length; j++) {
|
||||
const renderTarget = renderTargets[j];
|
||||
renderTarget.dispose();
|
||||
}
|
||||
}
|
||||
};
|
||||
function addResolutionDefine(materialShader) {
|
||||
materialShader.defines.resolution = "vec2( " + sizeX.toFixed(1) + ", " + sizeY.toFixed(1) + " )";
|
||||
}
|
||||
this.addResolutionDefine = addResolutionDefine;
|
||||
function createShaderMaterial(computeFragmentShader, uniforms) {
|
||||
uniforms = uniforms || {};
|
||||
const material = new THREE.ShaderMaterial({
|
||||
uniforms,
|
||||
vertexShader: getPassThroughVertexShader(),
|
||||
fragmentShader: computeFragmentShader
|
||||
});
|
||||
addResolutionDefine(material);
|
||||
return material;
|
||||
}
|
||||
this.createShaderMaterial = createShaderMaterial;
|
||||
this.createRenderTarget = function(sizeXTexture, sizeYTexture, wrapS, wrapT, minFilter, magFilter) {
|
||||
sizeXTexture = sizeXTexture || sizeX;
|
||||
sizeYTexture = sizeYTexture || sizeY;
|
||||
wrapS = wrapS || THREE.ClampToEdgeWrapping;
|
||||
wrapT = wrapT || THREE.ClampToEdgeWrapping;
|
||||
minFilter = minFilter || THREE.NearestFilter;
|
||||
magFilter = magFilter || THREE.NearestFilter;
|
||||
const renderTarget = new THREE.WebGLRenderTarget(sizeXTexture, sizeYTexture, {
|
||||
wrapS,
|
||||
wrapT,
|
||||
minFilter,
|
||||
magFilter,
|
||||
format: THREE.RGBAFormat,
|
||||
type: dataType,
|
||||
depthBuffer: false
|
||||
});
|
||||
return renderTarget;
|
||||
};
|
||||
this.createTexture = function() {
|
||||
const data = new Float32Array(sizeX * sizeY * 4);
|
||||
const texture = new THREE.DataTexture(data, sizeX, sizeY, THREE.RGBAFormat, THREE.FloatType);
|
||||
texture.needsUpdate = true;
|
||||
return texture;
|
||||
};
|
||||
this.renderTexture = function(input, output) {
|
||||
passThruUniforms.passThruTexture.value = input;
|
||||
this.doRenderTarget(passThruShader, output);
|
||||
passThruUniforms.passThruTexture.value = null;
|
||||
};
|
||||
this.doRenderTarget = function(material, output) {
|
||||
const currentRenderTarget = renderer.getRenderTarget();
|
||||
const currentXrEnabled = renderer.xr.enabled;
|
||||
const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;
|
||||
const currentOutputColorSpace = renderer.outputColorSpace;
|
||||
const currentToneMapping = renderer.toneMapping;
|
||||
renderer.xr.enabled = false;
|
||||
renderer.shadowMap.autoUpdate = false;
|
||||
if ("outputColorSpace" in renderer)
|
||||
renderer.outputColorSpace = "srgb-linear";
|
||||
else
|
||||
renderer.encoding = 3e3;
|
||||
renderer.toneMapping = THREE.NoToneMapping;
|
||||
mesh.material = material;
|
||||
renderer.setRenderTarget(output);
|
||||
renderer.render(scene, camera);
|
||||
mesh.material = passThruShader;
|
||||
renderer.xr.enabled = currentXrEnabled;
|
||||
renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
|
||||
renderer.outputColorSpace = currentOutputColorSpace;
|
||||
renderer.toneMapping = currentToneMapping;
|
||||
renderer.setRenderTarget(currentRenderTarget);
|
||||
};
|
||||
function getPassThroughVertexShader() {
|
||||
return "void main() {\n\n gl_Position = vec4( position, 1.0 );\n\n}\n";
|
||||
}
|
||||
function getPassThroughFragmentShader() {
|
||||
return "uniform sampler2D passThruTexture;\n\nvoid main() {\n\n vec2 uv = gl_FragCoord.xy / resolution.xy;\n\n gl_FragColor = texture2D( passThruTexture, uv );\n\n}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.GPUComputationRenderer = GPUComputationRenderer;
|
||||
//# sourceMappingURL=GPUComputationRenderer.cjs.map
|
||||
1
node_modules/three-stdlib/misc/GPUComputationRenderer.cjs.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/GPUComputationRenderer.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
53
node_modules/three-stdlib/misc/GPUComputationRenderer.d.ts
generated
vendored
Normal file
53
node_modules/three-stdlib/misc/GPUComputationRenderer.d.ts
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
import {
|
||||
WebGLRenderer,
|
||||
WebGLRenderTarget,
|
||||
Texture,
|
||||
DataTexture,
|
||||
Material,
|
||||
ShaderMaterial,
|
||||
Wrapping,
|
||||
TextureFilter,
|
||||
TextureDataType,
|
||||
IUniform,
|
||||
} from 'three'
|
||||
|
||||
export interface Variable {
|
||||
name: string
|
||||
initialValueTexture: Texture
|
||||
material: ShaderMaterial
|
||||
dependencies: Variable[]
|
||||
renderTargets: WebGLRenderTarget[]
|
||||
wrapS: number
|
||||
wrapT: number
|
||||
minFilter: number
|
||||
magFilter: number
|
||||
}
|
||||
|
||||
export class GPUComputationRenderer {
|
||||
constructor(sizeX: number, sizeY: number, renderer: WebGLRenderer)
|
||||
|
||||
setDataType(type: TextureDataType): void
|
||||
|
||||
addVariable(variableName: string, computeFragmentShader: string, initialValueTexture: Texture): Variable
|
||||
setVariableDependencies(variable: Variable, dependencies: Variable[] | null): void
|
||||
|
||||
init(): string | null
|
||||
compute(): void
|
||||
|
||||
getCurrentRenderTarget(variable: Variable): WebGLRenderTarget
|
||||
getAlternateRenderTarget(variable: Variable): WebGLRenderTarget
|
||||
addResolutionDefine(materialShader: ShaderMaterial): void
|
||||
createShaderMaterial(computeFragmentShader: string, uniforms?: { [uniform: string]: IUniform }): ShaderMaterial
|
||||
createRenderTarget(
|
||||
sizeXTexture: number,
|
||||
sizeYTexture: number,
|
||||
wrapS: Wrapping,
|
||||
wrapT: number,
|
||||
minFilter: TextureFilter,
|
||||
magFilter: TextureFilter,
|
||||
): WebGLRenderTarget
|
||||
createTexture(): DataTexture
|
||||
renderTexture(input: Texture, output: Texture): void
|
||||
doRenderTarget(material: Material, output: WebGLRenderTarget): void
|
||||
dispose(): void
|
||||
}
|
||||
206
node_modules/three-stdlib/misc/GPUComputationRenderer.js
generated
vendored
Normal file
206
node_modules/three-stdlib/misc/GPUComputationRenderer.js
generated
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
import { Scene, Camera, Mesh, PlaneGeometry, ShaderMaterial, WebGLRenderTarget, RGBAFormat, DataTexture, FloatType, NoToneMapping, NearestFilter, ClampToEdgeWrapping } from "three";
|
||||
class GPUComputationRenderer {
|
||||
constructor(sizeX, sizeY, renderer) {
|
||||
this.variables = [];
|
||||
this.currentTextureIndex = 0;
|
||||
let dataType = FloatType;
|
||||
const scene = new Scene();
|
||||
const camera = new Camera();
|
||||
camera.position.z = 1;
|
||||
const passThruUniforms = {
|
||||
passThruTexture: { value: null }
|
||||
};
|
||||
const passThruShader = createShaderMaterial(getPassThroughFragmentShader(), passThruUniforms);
|
||||
const mesh = new Mesh(new PlaneGeometry(2, 2), passThruShader);
|
||||
scene.add(mesh);
|
||||
this.setDataType = function(type) {
|
||||
dataType = type;
|
||||
return this;
|
||||
};
|
||||
this.addVariable = function(variableName, computeFragmentShader, initialValueTexture) {
|
||||
const material = this.createShaderMaterial(computeFragmentShader);
|
||||
const variable = {
|
||||
name: variableName,
|
||||
initialValueTexture,
|
||||
material,
|
||||
dependencies: null,
|
||||
renderTargets: [],
|
||||
wrapS: null,
|
||||
wrapT: null,
|
||||
minFilter: NearestFilter,
|
||||
magFilter: NearestFilter
|
||||
};
|
||||
this.variables.push(variable);
|
||||
return variable;
|
||||
};
|
||||
this.setVariableDependencies = function(variable, dependencies) {
|
||||
variable.dependencies = dependencies;
|
||||
};
|
||||
this.init = function() {
|
||||
if (renderer.capabilities.isWebGL2 === false && renderer.extensions.has("OES_texture_float") === false) {
|
||||
return "No OES_texture_float support for float textures.";
|
||||
}
|
||||
if (renderer.capabilities.maxVertexTextures === 0) {
|
||||
return "No support for vertex shader textures.";
|
||||
}
|
||||
for (let i = 0; i < this.variables.length; i++) {
|
||||
const variable = this.variables[i];
|
||||
variable.renderTargets[0] = this.createRenderTarget(
|
||||
sizeX,
|
||||
sizeY,
|
||||
variable.wrapS,
|
||||
variable.wrapT,
|
||||
variable.minFilter,
|
||||
variable.magFilter
|
||||
);
|
||||
variable.renderTargets[1] = this.createRenderTarget(
|
||||
sizeX,
|
||||
sizeY,
|
||||
variable.wrapS,
|
||||
variable.wrapT,
|
||||
variable.minFilter,
|
||||
variable.magFilter
|
||||
);
|
||||
this.renderTexture(variable.initialValueTexture, variable.renderTargets[0]);
|
||||
this.renderTexture(variable.initialValueTexture, variable.renderTargets[1]);
|
||||
const material = variable.material;
|
||||
const uniforms = material.uniforms;
|
||||
if (variable.dependencies !== null) {
|
||||
for (let d = 0; d < variable.dependencies.length; d++) {
|
||||
const depVar = variable.dependencies[d];
|
||||
if (depVar.name !== variable.name) {
|
||||
let found = false;
|
||||
for (let j = 0; j < this.variables.length; j++) {
|
||||
if (depVar.name === this.variables[j].name) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
return "Variable dependency not found. Variable=" + variable.name + ", dependency=" + depVar.name;
|
||||
}
|
||||
}
|
||||
uniforms[depVar.name] = { value: null };
|
||||
material.fragmentShader = "\nuniform sampler2D " + depVar.name + ";\n" + material.fragmentShader;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.currentTextureIndex = 0;
|
||||
return null;
|
||||
};
|
||||
this.compute = function() {
|
||||
const currentTextureIndex = this.currentTextureIndex;
|
||||
const nextTextureIndex = this.currentTextureIndex === 0 ? 1 : 0;
|
||||
for (let i = 0, il = this.variables.length; i < il; i++) {
|
||||
const variable = this.variables[i];
|
||||
if (variable.dependencies !== null) {
|
||||
const uniforms = variable.material.uniforms;
|
||||
for (let d = 0, dl = variable.dependencies.length; d < dl; d++) {
|
||||
const depVar = variable.dependencies[d];
|
||||
uniforms[depVar.name].value = depVar.renderTargets[currentTextureIndex].texture;
|
||||
}
|
||||
}
|
||||
this.doRenderTarget(variable.material, variable.renderTargets[nextTextureIndex]);
|
||||
}
|
||||
this.currentTextureIndex = nextTextureIndex;
|
||||
};
|
||||
this.getCurrentRenderTarget = function(variable) {
|
||||
return variable.renderTargets[this.currentTextureIndex];
|
||||
};
|
||||
this.getAlternateRenderTarget = function(variable) {
|
||||
return variable.renderTargets[this.currentTextureIndex === 0 ? 1 : 0];
|
||||
};
|
||||
this.dispose = function() {
|
||||
mesh.geometry.dispose();
|
||||
mesh.material.dispose();
|
||||
const variables = this.variables;
|
||||
for (let i = 0; i < variables.length; i++) {
|
||||
const variable = variables[i];
|
||||
if (variable.initialValueTexture)
|
||||
variable.initialValueTexture.dispose();
|
||||
const renderTargets = variable.renderTargets;
|
||||
for (let j = 0; j < renderTargets.length; j++) {
|
||||
const renderTarget = renderTargets[j];
|
||||
renderTarget.dispose();
|
||||
}
|
||||
}
|
||||
};
|
||||
function addResolutionDefine(materialShader) {
|
||||
materialShader.defines.resolution = "vec2( " + sizeX.toFixed(1) + ", " + sizeY.toFixed(1) + " )";
|
||||
}
|
||||
this.addResolutionDefine = addResolutionDefine;
|
||||
function createShaderMaterial(computeFragmentShader, uniforms) {
|
||||
uniforms = uniforms || {};
|
||||
const material = new ShaderMaterial({
|
||||
uniforms,
|
||||
vertexShader: getPassThroughVertexShader(),
|
||||
fragmentShader: computeFragmentShader
|
||||
});
|
||||
addResolutionDefine(material);
|
||||
return material;
|
||||
}
|
||||
this.createShaderMaterial = createShaderMaterial;
|
||||
this.createRenderTarget = function(sizeXTexture, sizeYTexture, wrapS, wrapT, minFilter, magFilter) {
|
||||
sizeXTexture = sizeXTexture || sizeX;
|
||||
sizeYTexture = sizeYTexture || sizeY;
|
||||
wrapS = wrapS || ClampToEdgeWrapping;
|
||||
wrapT = wrapT || ClampToEdgeWrapping;
|
||||
minFilter = minFilter || NearestFilter;
|
||||
magFilter = magFilter || NearestFilter;
|
||||
const renderTarget = new WebGLRenderTarget(sizeXTexture, sizeYTexture, {
|
||||
wrapS,
|
||||
wrapT,
|
||||
minFilter,
|
||||
magFilter,
|
||||
format: RGBAFormat,
|
||||
type: dataType,
|
||||
depthBuffer: false
|
||||
});
|
||||
return renderTarget;
|
||||
};
|
||||
this.createTexture = function() {
|
||||
const data = new Float32Array(sizeX * sizeY * 4);
|
||||
const texture = new DataTexture(data, sizeX, sizeY, RGBAFormat, FloatType);
|
||||
texture.needsUpdate = true;
|
||||
return texture;
|
||||
};
|
||||
this.renderTexture = function(input, output) {
|
||||
passThruUniforms.passThruTexture.value = input;
|
||||
this.doRenderTarget(passThruShader, output);
|
||||
passThruUniforms.passThruTexture.value = null;
|
||||
};
|
||||
this.doRenderTarget = function(material, output) {
|
||||
const currentRenderTarget = renderer.getRenderTarget();
|
||||
const currentXrEnabled = renderer.xr.enabled;
|
||||
const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;
|
||||
const currentOutputColorSpace = renderer.outputColorSpace;
|
||||
const currentToneMapping = renderer.toneMapping;
|
||||
renderer.xr.enabled = false;
|
||||
renderer.shadowMap.autoUpdate = false;
|
||||
if ("outputColorSpace" in renderer)
|
||||
renderer.outputColorSpace = "srgb-linear";
|
||||
else
|
||||
renderer.encoding = 3e3;
|
||||
renderer.toneMapping = NoToneMapping;
|
||||
mesh.material = material;
|
||||
renderer.setRenderTarget(output);
|
||||
renderer.render(scene, camera);
|
||||
mesh.material = passThruShader;
|
||||
renderer.xr.enabled = currentXrEnabled;
|
||||
renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
|
||||
renderer.outputColorSpace = currentOutputColorSpace;
|
||||
renderer.toneMapping = currentToneMapping;
|
||||
renderer.setRenderTarget(currentRenderTarget);
|
||||
};
|
||||
function getPassThroughVertexShader() {
|
||||
return "void main() {\n\n gl_Position = vec4( position, 1.0 );\n\n}\n";
|
||||
}
|
||||
function getPassThroughFragmentShader() {
|
||||
return "uniform sampler2D passThruTexture;\n\nvoid main() {\n\n vec2 uv = gl_FragCoord.xy / resolution.xy;\n\n gl_FragColor = texture2D( passThruTexture, uv );\n\n}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
export {
|
||||
GPUComputationRenderer
|
||||
};
|
||||
//# sourceMappingURL=GPUComputationRenderer.js.map
|
||||
1
node_modules/three-stdlib/misc/GPUComputationRenderer.js.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/GPUComputationRenderer.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
34
node_modules/three-stdlib/misc/Gyroscope.cjs
generated
vendored
Normal file
34
node_modules/three-stdlib/misc/Gyroscope.cjs
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
||||
const THREE = require("three");
|
||||
const _translationObject = /* @__PURE__ */ new THREE.Vector3();
|
||||
const _quaternionObject = /* @__PURE__ */ new THREE.Quaternion();
|
||||
const _scaleObject = /* @__PURE__ */ new THREE.Vector3();
|
||||
const _translationWorld = /* @__PURE__ */ new THREE.Vector3();
|
||||
const _quaternionWorld = /* @__PURE__ */ new THREE.Quaternion();
|
||||
const _scaleWorld = /* @__PURE__ */ new THREE.Vector3();
|
||||
class Gyroscope extends THREE.Object3D {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
updateMatrixWorld(force) {
|
||||
this.matrixAutoUpdate && this.updateMatrix();
|
||||
if (this.matrixWorldNeedsUpdate || force) {
|
||||
if (this.parent !== null) {
|
||||
this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix);
|
||||
this.matrixWorld.decompose(_translationWorld, _quaternionWorld, _scaleWorld);
|
||||
this.matrix.decompose(_translationObject, _quaternionObject, _scaleObject);
|
||||
this.matrixWorld.compose(_translationWorld, _quaternionObject, _scaleWorld);
|
||||
} else {
|
||||
this.matrixWorld.copy(this.matrix);
|
||||
}
|
||||
this.matrixWorldNeedsUpdate = false;
|
||||
force = true;
|
||||
}
|
||||
for (let i = 0, l = this.children.length; i < l; i++) {
|
||||
this.children[i].updateMatrixWorld(force);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.Gyroscope = Gyroscope;
|
||||
//# sourceMappingURL=Gyroscope.cjs.map
|
||||
1
node_modules/three-stdlib/misc/Gyroscope.cjs.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/Gyroscope.cjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"Gyroscope.cjs","sources":["../../src/misc/Gyroscope.js"],"sourcesContent":["import { Object3D, Quaternion, Vector3 } from 'three'\n\nconst _translationObject = /* @__PURE__ */ new Vector3()\nconst _quaternionObject = /* @__PURE__ */ new Quaternion()\nconst _scaleObject = /* @__PURE__ */ new Vector3()\n\nconst _translationWorld = /* @__PURE__ */ new Vector3()\nconst _quaternionWorld = /* @__PURE__ */ new Quaternion()\nconst _scaleWorld = /* @__PURE__ */ new Vector3()\n\nclass Gyroscope extends Object3D {\n constructor() {\n super()\n }\n\n updateMatrixWorld(force) {\n this.matrixAutoUpdate && this.updateMatrix()\n\n // update matrixWorld\n\n if (this.matrixWorldNeedsUpdate || force) {\n if (this.parent !== null) {\n this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix)\n\n this.matrixWorld.decompose(_translationWorld, _quaternionWorld, _scaleWorld)\n this.matrix.decompose(_translationObject, _quaternionObject, _scaleObject)\n\n this.matrixWorld.compose(_translationWorld, _quaternionObject, _scaleWorld)\n } else {\n this.matrixWorld.copy(this.matrix)\n }\n\n this.matrixWorldNeedsUpdate = false\n\n force = true\n }\n\n // update children\n\n for (let i = 0, l = this.children.length; i < l; i++) {\n this.children[i].updateMatrixWorld(force)\n }\n }\n}\n\nexport { Gyroscope }\n"],"names":["Vector3","Quaternion","Object3D"],"mappings":";;;AAEA,MAAM,qBAAqC,oBAAIA,MAAAA,QAAS;AACxD,MAAM,oBAAoC,oBAAIC,MAAAA,WAAY;AAC1D,MAAM,eAA+B,oBAAID,MAAAA,QAAS;AAElD,MAAM,oBAAoC,oBAAIA,MAAAA,QAAS;AACvD,MAAM,mBAAmC,oBAAIC,MAAAA,WAAY;AACzD,MAAM,cAA8B,oBAAID,MAAAA,QAAS;AAEjD,MAAM,kBAAkBE,MAAAA,SAAS;AAAA,EAC/B,cAAc;AACZ,UAAO;AAAA,EACR;AAAA,EAED,kBAAkB,OAAO;AACvB,SAAK,oBAAoB,KAAK,aAAc;AAI5C,QAAI,KAAK,0BAA0B,OAAO;AACxC,UAAI,KAAK,WAAW,MAAM;AACxB,aAAK,YAAY,iBAAiB,KAAK,OAAO,aAAa,KAAK,MAAM;AAEtE,aAAK,YAAY,UAAU,mBAAmB,kBAAkB,WAAW;AAC3E,aAAK,OAAO,UAAU,oBAAoB,mBAAmB,YAAY;AAEzE,aAAK,YAAY,QAAQ,mBAAmB,mBAAmB,WAAW;AAAA,MAClF,OAAa;AACL,aAAK,YAAY,KAAK,KAAK,MAAM;AAAA,MAClC;AAED,WAAK,yBAAyB;AAE9B,cAAQ;AAAA,IACT;AAID,aAAS,IAAI,GAAG,IAAI,KAAK,SAAS,QAAQ,IAAI,GAAG,KAAK;AACpD,WAAK,SAAS,CAAC,EAAE,kBAAkB,KAAK;AAAA,IACzC;AAAA,EACF;AACH;;"}
|
||||
5
node_modules/three-stdlib/misc/Gyroscope.d.ts
generated
vendored
Normal file
5
node_modules/three-stdlib/misc/Gyroscope.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import { Object3D } from 'three'
|
||||
|
||||
export class Gyroscope extends Object3D {
|
||||
constructor()
|
||||
}
|
||||
34
node_modules/three-stdlib/misc/Gyroscope.js
generated
vendored
Normal file
34
node_modules/three-stdlib/misc/Gyroscope.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
import { Object3D, Vector3, Quaternion } from "three";
|
||||
const _translationObject = /* @__PURE__ */ new Vector3();
|
||||
const _quaternionObject = /* @__PURE__ */ new Quaternion();
|
||||
const _scaleObject = /* @__PURE__ */ new Vector3();
|
||||
const _translationWorld = /* @__PURE__ */ new Vector3();
|
||||
const _quaternionWorld = /* @__PURE__ */ new Quaternion();
|
||||
const _scaleWorld = /* @__PURE__ */ new Vector3();
|
||||
class Gyroscope extends Object3D {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
updateMatrixWorld(force) {
|
||||
this.matrixAutoUpdate && this.updateMatrix();
|
||||
if (this.matrixWorldNeedsUpdate || force) {
|
||||
if (this.parent !== null) {
|
||||
this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix);
|
||||
this.matrixWorld.decompose(_translationWorld, _quaternionWorld, _scaleWorld);
|
||||
this.matrix.decompose(_translationObject, _quaternionObject, _scaleObject);
|
||||
this.matrixWorld.compose(_translationWorld, _quaternionObject, _scaleWorld);
|
||||
} else {
|
||||
this.matrixWorld.copy(this.matrix);
|
||||
}
|
||||
this.matrixWorldNeedsUpdate = false;
|
||||
force = true;
|
||||
}
|
||||
for (let i = 0, l = this.children.length; i < l; i++) {
|
||||
this.children[i].updateMatrixWorld(force);
|
||||
}
|
||||
}
|
||||
}
|
||||
export {
|
||||
Gyroscope
|
||||
};
|
||||
//# sourceMappingURL=Gyroscope.js.map
|
||||
1
node_modules/three-stdlib/misc/Gyroscope.js.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/Gyroscope.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"Gyroscope.js","sources":["../../src/misc/Gyroscope.js"],"sourcesContent":["import { Object3D, Quaternion, Vector3 } from 'three'\n\nconst _translationObject = /* @__PURE__ */ new Vector3()\nconst _quaternionObject = /* @__PURE__ */ new Quaternion()\nconst _scaleObject = /* @__PURE__ */ new Vector3()\n\nconst _translationWorld = /* @__PURE__ */ new Vector3()\nconst _quaternionWorld = /* @__PURE__ */ new Quaternion()\nconst _scaleWorld = /* @__PURE__ */ new Vector3()\n\nclass Gyroscope extends Object3D {\n constructor() {\n super()\n }\n\n updateMatrixWorld(force) {\n this.matrixAutoUpdate && this.updateMatrix()\n\n // update matrixWorld\n\n if (this.matrixWorldNeedsUpdate || force) {\n if (this.parent !== null) {\n this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix)\n\n this.matrixWorld.decompose(_translationWorld, _quaternionWorld, _scaleWorld)\n this.matrix.decompose(_translationObject, _quaternionObject, _scaleObject)\n\n this.matrixWorld.compose(_translationWorld, _quaternionObject, _scaleWorld)\n } else {\n this.matrixWorld.copy(this.matrix)\n }\n\n this.matrixWorldNeedsUpdate = false\n\n force = true\n }\n\n // update children\n\n for (let i = 0, l = this.children.length; i < l; i++) {\n this.children[i].updateMatrixWorld(force)\n }\n }\n}\n\nexport { Gyroscope }\n"],"names":[],"mappings":";AAEA,MAAM,qBAAqC,oBAAI,QAAS;AACxD,MAAM,oBAAoC,oBAAI,WAAY;AAC1D,MAAM,eAA+B,oBAAI,QAAS;AAElD,MAAM,oBAAoC,oBAAI,QAAS;AACvD,MAAM,mBAAmC,oBAAI,WAAY;AACzD,MAAM,cAA8B,oBAAI,QAAS;AAEjD,MAAM,kBAAkB,SAAS;AAAA,EAC/B,cAAc;AACZ,UAAO;AAAA,EACR;AAAA,EAED,kBAAkB,OAAO;AACvB,SAAK,oBAAoB,KAAK,aAAc;AAI5C,QAAI,KAAK,0BAA0B,OAAO;AACxC,UAAI,KAAK,WAAW,MAAM;AACxB,aAAK,YAAY,iBAAiB,KAAK,OAAO,aAAa,KAAK,MAAM;AAEtE,aAAK,YAAY,UAAU,mBAAmB,kBAAkB,WAAW;AAC3E,aAAK,OAAO,UAAU,oBAAoB,mBAAmB,YAAY;AAEzE,aAAK,YAAY,QAAQ,mBAAmB,mBAAmB,WAAW;AAAA,MAClF,OAAa;AACL,aAAK,YAAY,KAAK,KAAK,MAAM;AAAA,MAClC;AAED,WAAK,yBAAyB;AAE9B,cAAQ;AAAA,IACT;AAID,aAAS,IAAI,GAAG,IAAI,KAAK,SAAS,QAAQ,IAAI,GAAG,KAAK;AACpD,WAAK,SAAS,CAAC,EAAE,kBAAkB,KAAK;AAAA,IACzC;AAAA,EACF;AACH;"}
|
||||
168
node_modules/three-stdlib/misc/MD2Character.cjs
generated
vendored
Normal file
168
node_modules/three-stdlib/misc/MD2Character.cjs
generated
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
||||
const THREE = require("three");
|
||||
const MD2Loader = require("../loaders/MD2Loader.cjs");
|
||||
class MD2Character {
|
||||
constructor() {
|
||||
this.scale = 1;
|
||||
this.animationFPS = 6;
|
||||
this.root = new THREE.Object3D();
|
||||
this.meshBody = null;
|
||||
this.meshWeapon = null;
|
||||
this.skinsBody = [];
|
||||
this.skinsWeapon = [];
|
||||
this.weapons = [];
|
||||
this.activeAnimation = null;
|
||||
this.mixer = null;
|
||||
this.onLoadComplete = function() {
|
||||
};
|
||||
this.loadCounter = 0;
|
||||
}
|
||||
loadParts(config) {
|
||||
const scope = this;
|
||||
function createPart(geometry, skinMap) {
|
||||
const materialWireframe = new THREE.MeshLambertMaterial({
|
||||
color: 16755200,
|
||||
wireframe: true,
|
||||
morphTargets: true,
|
||||
morphNormals: true
|
||||
});
|
||||
const materialTexture = new THREE.MeshLambertMaterial({
|
||||
color: 16777215,
|
||||
wireframe: false,
|
||||
map: skinMap,
|
||||
morphTargets: true,
|
||||
morphNormals: true
|
||||
});
|
||||
const mesh = new THREE.Mesh(geometry, materialTexture);
|
||||
mesh.rotation.y = -Math.PI / 2;
|
||||
mesh.castShadow = true;
|
||||
mesh.receiveShadow = true;
|
||||
mesh.materialTexture = materialTexture;
|
||||
mesh.materialWireframe = materialWireframe;
|
||||
return mesh;
|
||||
}
|
||||
function loadTextures(baseUrl, textureUrls) {
|
||||
const textureLoader = new THREE.TextureLoader();
|
||||
const textures = [];
|
||||
for (let i = 0; i < textureUrls.length; i++) {
|
||||
textures[i] = textureLoader.load(baseUrl + textureUrls[i], checkLoadingComplete);
|
||||
textures[i].mapping = THREE.UVMapping;
|
||||
textures[i].name = textureUrls[i];
|
||||
if ("colorSpace" in textures[i])
|
||||
textures[i].colorSpace = "srgb";
|
||||
else
|
||||
textures[i].encoding = 3001;
|
||||
}
|
||||
return textures;
|
||||
}
|
||||
function checkLoadingComplete() {
|
||||
scope.loadCounter -= 1;
|
||||
if (scope.loadCounter === 0)
|
||||
scope.onLoadComplete();
|
||||
}
|
||||
this.loadCounter = config.weapons.length * 2 + config.skins.length + 1;
|
||||
const weaponsTextures = [];
|
||||
for (let i = 0; i < config.weapons.length; i++)
|
||||
weaponsTextures[i] = config.weapons[i][1];
|
||||
this.skinsBody = loadTextures(config.baseUrl + "skins/", config.skins);
|
||||
this.skinsWeapon = loadTextures(config.baseUrl + "skins/", weaponsTextures);
|
||||
const loader = new MD2Loader.MD2Loader();
|
||||
loader.load(config.baseUrl + config.body, function(geo) {
|
||||
const boundingBox = new THREE.Box3();
|
||||
boundingBox.setFromBufferAttribute(geo.attributes.position);
|
||||
scope.root.position.y = -scope.scale * boundingBox.min.y;
|
||||
const mesh = createPart(geo, scope.skinsBody[0]);
|
||||
mesh.scale.set(scope.scale, scope.scale, scope.scale);
|
||||
scope.root.add(mesh);
|
||||
scope.meshBody = mesh;
|
||||
scope.meshBody.clipOffset = 0;
|
||||
scope.activeAnimationClipName = mesh.geometry.animations[0].name;
|
||||
scope.mixer = new THREE.AnimationMixer(mesh);
|
||||
checkLoadingComplete();
|
||||
});
|
||||
const generateCallback = function(index, name) {
|
||||
return function(geo) {
|
||||
const mesh = createPart(geo, scope.skinsWeapon[index]);
|
||||
mesh.scale.set(scope.scale, scope.scale, scope.scale);
|
||||
mesh.visible = false;
|
||||
mesh.name = name;
|
||||
scope.root.add(mesh);
|
||||
scope.weapons[index] = mesh;
|
||||
scope.meshWeapon = mesh;
|
||||
checkLoadingComplete();
|
||||
};
|
||||
};
|
||||
for (let i = 0; i < config.weapons.length; i++) {
|
||||
loader.load(config.baseUrl + config.weapons[i][0], generateCallback(i, config.weapons[i][0]));
|
||||
}
|
||||
}
|
||||
setPlaybackRate(rate) {
|
||||
if (rate !== 0) {
|
||||
this.mixer.timeScale = 1 / rate;
|
||||
} else {
|
||||
this.mixer.timeScale = 0;
|
||||
}
|
||||
}
|
||||
setWireframe(wireframeEnabled) {
|
||||
if (wireframeEnabled) {
|
||||
if (this.meshBody)
|
||||
this.meshBody.material = this.meshBody.materialWireframe;
|
||||
if (this.meshWeapon)
|
||||
this.meshWeapon.material = this.meshWeapon.materialWireframe;
|
||||
} else {
|
||||
if (this.meshBody)
|
||||
this.meshBody.material = this.meshBody.materialTexture;
|
||||
if (this.meshWeapon)
|
||||
this.meshWeapon.material = this.meshWeapon.materialTexture;
|
||||
}
|
||||
}
|
||||
setSkin(index) {
|
||||
if (this.meshBody && this.meshBody.material.wireframe === false) {
|
||||
this.meshBody.material.map = this.skinsBody[index];
|
||||
}
|
||||
}
|
||||
setWeapon(index) {
|
||||
for (let i = 0; i < this.weapons.length; i++)
|
||||
this.weapons[i].visible = false;
|
||||
const activeWeapon = this.weapons[index];
|
||||
if (activeWeapon) {
|
||||
activeWeapon.visible = true;
|
||||
this.meshWeapon = activeWeapon;
|
||||
this.syncWeaponAnimation();
|
||||
}
|
||||
}
|
||||
setAnimation(clipName) {
|
||||
if (this.meshBody) {
|
||||
if (this.meshBody.activeAction) {
|
||||
this.meshBody.activeAction.stop();
|
||||
this.meshBody.activeAction = null;
|
||||
}
|
||||
const action = this.mixer.clipAction(clipName, this.meshBody);
|
||||
if (action) {
|
||||
this.meshBody.activeAction = action.play();
|
||||
}
|
||||
}
|
||||
this.activeClipName = clipName;
|
||||
this.syncWeaponAnimation();
|
||||
}
|
||||
syncWeaponAnimation() {
|
||||
const clipName = this.activeClipName;
|
||||
if (this.meshWeapon) {
|
||||
if (this.meshWeapon.activeAction) {
|
||||
this.meshWeapon.activeAction.stop();
|
||||
this.meshWeapon.activeAction = null;
|
||||
}
|
||||
const action = this.mixer.clipAction(clipName, this.meshWeapon);
|
||||
if (action) {
|
||||
this.meshWeapon.activeAction = action.syncWith(this.meshBody.activeAction).play();
|
||||
}
|
||||
}
|
||||
}
|
||||
update(delta) {
|
||||
if (this.mixer)
|
||||
this.mixer.update(delta);
|
||||
}
|
||||
}
|
||||
exports.MD2Character = MD2Character;
|
||||
//# sourceMappingURL=MD2Character.cjs.map
|
||||
1
node_modules/three-stdlib/misc/MD2Character.cjs.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/MD2Character.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
33
node_modules/three-stdlib/misc/MD2Character.d.ts
generated
vendored
Normal file
33
node_modules/three-stdlib/misc/MD2Character.d.ts
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
import { Object3D, Mesh, Texture, AnimationMixer } from 'three'
|
||||
|
||||
export interface MD2PartsConfig {
|
||||
baseUrl: string
|
||||
body: string
|
||||
skins: string[]
|
||||
weapons: Array<[string, string]>
|
||||
}
|
||||
|
||||
export class MD2Character {
|
||||
constructor()
|
||||
scale: number
|
||||
animationFPS: number
|
||||
root: Object3D
|
||||
meshBody: Mesh | null
|
||||
meshWeapon: Mesh | null
|
||||
skinsBody: Texture[]
|
||||
skinsWeapon: Texture[]
|
||||
weapons: Mesh[]
|
||||
activeAnimation: string | null
|
||||
mixer: AnimationMixer | null
|
||||
loadCounter: number
|
||||
|
||||
onLoadComplete(): void
|
||||
loadParts(config: MD2PartsConfig): void
|
||||
setPlaybackRate(rate: number): void
|
||||
setWireframe(wireframeEnabled: boolean): void
|
||||
setSkin(index: number): void
|
||||
setWeapon(index: number): void
|
||||
setAnimation(clipName: string): void
|
||||
syncWeaponAnimation(): void
|
||||
update(delta: number): void
|
||||
}
|
||||
168
node_modules/three-stdlib/misc/MD2Character.js
generated
vendored
Normal file
168
node_modules/three-stdlib/misc/MD2Character.js
generated
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
import { Object3D, Box3, AnimationMixer, MeshLambertMaterial, Mesh, TextureLoader, UVMapping } from "three";
|
||||
import { MD2Loader } from "../loaders/MD2Loader.js";
|
||||
class MD2Character {
|
||||
constructor() {
|
||||
this.scale = 1;
|
||||
this.animationFPS = 6;
|
||||
this.root = new Object3D();
|
||||
this.meshBody = null;
|
||||
this.meshWeapon = null;
|
||||
this.skinsBody = [];
|
||||
this.skinsWeapon = [];
|
||||
this.weapons = [];
|
||||
this.activeAnimation = null;
|
||||
this.mixer = null;
|
||||
this.onLoadComplete = function() {
|
||||
};
|
||||
this.loadCounter = 0;
|
||||
}
|
||||
loadParts(config) {
|
||||
const scope = this;
|
||||
function createPart(geometry, skinMap) {
|
||||
const materialWireframe = new MeshLambertMaterial({
|
||||
color: 16755200,
|
||||
wireframe: true,
|
||||
morphTargets: true,
|
||||
morphNormals: true
|
||||
});
|
||||
const materialTexture = new MeshLambertMaterial({
|
||||
color: 16777215,
|
||||
wireframe: false,
|
||||
map: skinMap,
|
||||
morphTargets: true,
|
||||
morphNormals: true
|
||||
});
|
||||
const mesh = new Mesh(geometry, materialTexture);
|
||||
mesh.rotation.y = -Math.PI / 2;
|
||||
mesh.castShadow = true;
|
||||
mesh.receiveShadow = true;
|
||||
mesh.materialTexture = materialTexture;
|
||||
mesh.materialWireframe = materialWireframe;
|
||||
return mesh;
|
||||
}
|
||||
function loadTextures(baseUrl, textureUrls) {
|
||||
const textureLoader = new TextureLoader();
|
||||
const textures = [];
|
||||
for (let i = 0; i < textureUrls.length; i++) {
|
||||
textures[i] = textureLoader.load(baseUrl + textureUrls[i], checkLoadingComplete);
|
||||
textures[i].mapping = UVMapping;
|
||||
textures[i].name = textureUrls[i];
|
||||
if ("colorSpace" in textures[i])
|
||||
textures[i].colorSpace = "srgb";
|
||||
else
|
||||
textures[i].encoding = 3001;
|
||||
}
|
||||
return textures;
|
||||
}
|
||||
function checkLoadingComplete() {
|
||||
scope.loadCounter -= 1;
|
||||
if (scope.loadCounter === 0)
|
||||
scope.onLoadComplete();
|
||||
}
|
||||
this.loadCounter = config.weapons.length * 2 + config.skins.length + 1;
|
||||
const weaponsTextures = [];
|
||||
for (let i = 0; i < config.weapons.length; i++)
|
||||
weaponsTextures[i] = config.weapons[i][1];
|
||||
this.skinsBody = loadTextures(config.baseUrl + "skins/", config.skins);
|
||||
this.skinsWeapon = loadTextures(config.baseUrl + "skins/", weaponsTextures);
|
||||
const loader = new MD2Loader();
|
||||
loader.load(config.baseUrl + config.body, function(geo) {
|
||||
const boundingBox = new Box3();
|
||||
boundingBox.setFromBufferAttribute(geo.attributes.position);
|
||||
scope.root.position.y = -scope.scale * boundingBox.min.y;
|
||||
const mesh = createPart(geo, scope.skinsBody[0]);
|
||||
mesh.scale.set(scope.scale, scope.scale, scope.scale);
|
||||
scope.root.add(mesh);
|
||||
scope.meshBody = mesh;
|
||||
scope.meshBody.clipOffset = 0;
|
||||
scope.activeAnimationClipName = mesh.geometry.animations[0].name;
|
||||
scope.mixer = new AnimationMixer(mesh);
|
||||
checkLoadingComplete();
|
||||
});
|
||||
const generateCallback = function(index, name) {
|
||||
return function(geo) {
|
||||
const mesh = createPart(geo, scope.skinsWeapon[index]);
|
||||
mesh.scale.set(scope.scale, scope.scale, scope.scale);
|
||||
mesh.visible = false;
|
||||
mesh.name = name;
|
||||
scope.root.add(mesh);
|
||||
scope.weapons[index] = mesh;
|
||||
scope.meshWeapon = mesh;
|
||||
checkLoadingComplete();
|
||||
};
|
||||
};
|
||||
for (let i = 0; i < config.weapons.length; i++) {
|
||||
loader.load(config.baseUrl + config.weapons[i][0], generateCallback(i, config.weapons[i][0]));
|
||||
}
|
||||
}
|
||||
setPlaybackRate(rate) {
|
||||
if (rate !== 0) {
|
||||
this.mixer.timeScale = 1 / rate;
|
||||
} else {
|
||||
this.mixer.timeScale = 0;
|
||||
}
|
||||
}
|
||||
setWireframe(wireframeEnabled) {
|
||||
if (wireframeEnabled) {
|
||||
if (this.meshBody)
|
||||
this.meshBody.material = this.meshBody.materialWireframe;
|
||||
if (this.meshWeapon)
|
||||
this.meshWeapon.material = this.meshWeapon.materialWireframe;
|
||||
} else {
|
||||
if (this.meshBody)
|
||||
this.meshBody.material = this.meshBody.materialTexture;
|
||||
if (this.meshWeapon)
|
||||
this.meshWeapon.material = this.meshWeapon.materialTexture;
|
||||
}
|
||||
}
|
||||
setSkin(index) {
|
||||
if (this.meshBody && this.meshBody.material.wireframe === false) {
|
||||
this.meshBody.material.map = this.skinsBody[index];
|
||||
}
|
||||
}
|
||||
setWeapon(index) {
|
||||
for (let i = 0; i < this.weapons.length; i++)
|
||||
this.weapons[i].visible = false;
|
||||
const activeWeapon = this.weapons[index];
|
||||
if (activeWeapon) {
|
||||
activeWeapon.visible = true;
|
||||
this.meshWeapon = activeWeapon;
|
||||
this.syncWeaponAnimation();
|
||||
}
|
||||
}
|
||||
setAnimation(clipName) {
|
||||
if (this.meshBody) {
|
||||
if (this.meshBody.activeAction) {
|
||||
this.meshBody.activeAction.stop();
|
||||
this.meshBody.activeAction = null;
|
||||
}
|
||||
const action = this.mixer.clipAction(clipName, this.meshBody);
|
||||
if (action) {
|
||||
this.meshBody.activeAction = action.play();
|
||||
}
|
||||
}
|
||||
this.activeClipName = clipName;
|
||||
this.syncWeaponAnimation();
|
||||
}
|
||||
syncWeaponAnimation() {
|
||||
const clipName = this.activeClipName;
|
||||
if (this.meshWeapon) {
|
||||
if (this.meshWeapon.activeAction) {
|
||||
this.meshWeapon.activeAction.stop();
|
||||
this.meshWeapon.activeAction = null;
|
||||
}
|
||||
const action = this.mixer.clipAction(clipName, this.meshWeapon);
|
||||
if (action) {
|
||||
this.meshWeapon.activeAction = action.syncWith(this.meshBody.activeAction).play();
|
||||
}
|
||||
}
|
||||
}
|
||||
update(delta) {
|
||||
if (this.mixer)
|
||||
this.mixer.update(delta);
|
||||
}
|
||||
}
|
||||
export {
|
||||
MD2Character
|
||||
};
|
||||
//# sourceMappingURL=MD2Character.js.map
|
||||
1
node_modules/three-stdlib/misc/MD2Character.js.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/MD2Character.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
333
node_modules/three-stdlib/misc/MD2CharacterComplex.cjs
generated
vendored
Normal file
333
node_modules/three-stdlib/misc/MD2CharacterComplex.cjs
generated
vendored
Normal file
@@ -0,0 +1,333 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
||||
const THREE = require("three");
|
||||
const MD2Loader = require("../loaders/MD2Loader.cjs");
|
||||
const MorphBlendMesh = require("./MorphBlendMesh.cjs");
|
||||
class MD2CharacterComplex {
|
||||
constructor() {
|
||||
this.scale = 1;
|
||||
this.animationFPS = 6;
|
||||
this.transitionFrames = 15;
|
||||
this.maxSpeed = 275;
|
||||
this.maxReverseSpeed = -275;
|
||||
this.frontAcceleration = 600;
|
||||
this.backAcceleration = 600;
|
||||
this.frontDecceleration = 600;
|
||||
this.angularSpeed = 2.5;
|
||||
this.root = new THREE.Object3D();
|
||||
this.meshBody = null;
|
||||
this.meshWeapon = null;
|
||||
this.controls = null;
|
||||
this.skinsBody = [];
|
||||
this.skinsWeapon = [];
|
||||
this.weapons = [];
|
||||
this.currentSkin = void 0;
|
||||
this.onLoadComplete = function() {
|
||||
};
|
||||
this.meshes = [];
|
||||
this.animations = {};
|
||||
this.loadCounter = 0;
|
||||
this.speed = 0;
|
||||
this.bodyOrientation = 0;
|
||||
this.walkSpeed = this.maxSpeed;
|
||||
this.crouchSpeed = this.maxSpeed * 0.5;
|
||||
this.activeAnimation = null;
|
||||
this.oldAnimation = null;
|
||||
}
|
||||
enableShadows(enable) {
|
||||
for (let i = 0; i < this.meshes.length; i++) {
|
||||
this.meshes[i].castShadow = enable;
|
||||
this.meshes[i].receiveShadow = enable;
|
||||
}
|
||||
}
|
||||
setVisible(enable) {
|
||||
for (let i = 0; i < this.meshes.length; i++) {
|
||||
this.meshes[i].visible = enable;
|
||||
this.meshes[i].visible = enable;
|
||||
}
|
||||
}
|
||||
shareParts(original) {
|
||||
this.animations = original.animations;
|
||||
this.walkSpeed = original.walkSpeed;
|
||||
this.crouchSpeed = original.crouchSpeed;
|
||||
this.skinsBody = original.skinsBody;
|
||||
this.skinsWeapon = original.skinsWeapon;
|
||||
const mesh = this._createPart(original.meshBody.geometry, this.skinsBody[0]);
|
||||
mesh.scale.set(this.scale, this.scale, this.scale);
|
||||
this.root.position.y = original.root.position.y;
|
||||
this.root.add(mesh);
|
||||
this.meshBody = mesh;
|
||||
this.meshes.push(mesh);
|
||||
for (let i = 0; i < original.weapons.length; i++) {
|
||||
const meshWeapon = this._createPart(original.weapons[i].geometry, this.skinsWeapon[i]);
|
||||
meshWeapon.scale.set(this.scale, this.scale, this.scale);
|
||||
meshWeapon.visible = false;
|
||||
meshWeapon.name = original.weapons[i].name;
|
||||
this.root.add(meshWeapon);
|
||||
this.weapons[i] = meshWeapon;
|
||||
this.meshWeapon = meshWeapon;
|
||||
this.meshes.push(meshWeapon);
|
||||
}
|
||||
}
|
||||
loadParts(config) {
|
||||
const scope = this;
|
||||
function loadTextures(baseUrl, textureUrls) {
|
||||
const textureLoader = new THREE.TextureLoader();
|
||||
const textures = [];
|
||||
for (let i = 0; i < textureUrls.length; i++) {
|
||||
textures[i] = textureLoader.load(baseUrl + textureUrls[i], checkLoadingComplete);
|
||||
textures[i].mapping = THREE.UVMapping;
|
||||
textures[i].name = textureUrls[i];
|
||||
if ("colorSpace" in textures[i])
|
||||
textures[i].colorSpace = "srgb";
|
||||
else
|
||||
textures[i].encoding = 3001;
|
||||
}
|
||||
return textures;
|
||||
}
|
||||
function checkLoadingComplete() {
|
||||
scope.loadCounter -= 1;
|
||||
if (scope.loadCounter === 0)
|
||||
scope.onLoadComplete();
|
||||
}
|
||||
this.animations = config.animations;
|
||||
this.walkSpeed = config.walkSpeed;
|
||||
this.crouchSpeed = config.crouchSpeed;
|
||||
this.loadCounter = config.weapons.length * 2 + config.skins.length + 1;
|
||||
const weaponsTextures = [];
|
||||
for (let i = 0; i < config.weapons.length; i++)
|
||||
weaponsTextures[i] = config.weapons[i][1];
|
||||
this.skinsBody = loadTextures(config.baseUrl + "skins/", config.skins);
|
||||
this.skinsWeapon = loadTextures(config.baseUrl + "skins/", weaponsTextures);
|
||||
const loader = new MD2Loader.MD2Loader();
|
||||
loader.load(config.baseUrl + config.body, function(geo) {
|
||||
const boundingBox = new THREE.Box3();
|
||||
boundingBox.setFromBufferAttribute(geo.attributes.position);
|
||||
scope.root.position.y = -scope.scale * boundingBox.min.y;
|
||||
const mesh = scope._createPart(geo, scope.skinsBody[0]);
|
||||
mesh.scale.set(scope.scale, scope.scale, scope.scale);
|
||||
scope.root.add(mesh);
|
||||
scope.meshBody = mesh;
|
||||
scope.meshes.push(mesh);
|
||||
checkLoadingComplete();
|
||||
});
|
||||
const generateCallback = function(index, name) {
|
||||
return function(geo) {
|
||||
const mesh = scope._createPart(geo, scope.skinsWeapon[index]);
|
||||
mesh.scale.set(scope.scale, scope.scale, scope.scale);
|
||||
mesh.visible = false;
|
||||
mesh.name = name;
|
||||
scope.root.add(mesh);
|
||||
scope.weapons[index] = mesh;
|
||||
scope.meshWeapon = mesh;
|
||||
scope.meshes.push(mesh);
|
||||
checkLoadingComplete();
|
||||
};
|
||||
};
|
||||
for (let i = 0; i < config.weapons.length; i++) {
|
||||
loader.load(config.baseUrl + config.weapons[i][0], generateCallback(i, config.weapons[i][0]));
|
||||
}
|
||||
}
|
||||
setPlaybackRate(rate) {
|
||||
if (this.meshBody)
|
||||
this.meshBody.duration = this.meshBody.baseDuration / rate;
|
||||
if (this.meshWeapon)
|
||||
this.meshWeapon.duration = this.meshWeapon.baseDuration / rate;
|
||||
}
|
||||
setWireframe(wireframeEnabled) {
|
||||
if (wireframeEnabled) {
|
||||
if (this.meshBody)
|
||||
this.meshBody.material = this.meshBody.materialWireframe;
|
||||
if (this.meshWeapon)
|
||||
this.meshWeapon.material = this.meshWeapon.materialWireframe;
|
||||
} else {
|
||||
if (this.meshBody)
|
||||
this.meshBody.material = this.meshBody.materialTexture;
|
||||
if (this.meshWeapon)
|
||||
this.meshWeapon.material = this.meshWeapon.materialTexture;
|
||||
}
|
||||
}
|
||||
setSkin(index) {
|
||||
if (this.meshBody && this.meshBody.material.wireframe === false) {
|
||||
this.meshBody.material.map = this.skinsBody[index];
|
||||
this.currentSkin = index;
|
||||
}
|
||||
}
|
||||
setWeapon(index) {
|
||||
for (let i = 0; i < this.weapons.length; i++)
|
||||
this.weapons[i].visible = false;
|
||||
const activeWeapon = this.weapons[index];
|
||||
if (activeWeapon) {
|
||||
activeWeapon.visible = true;
|
||||
this.meshWeapon = activeWeapon;
|
||||
if (this.activeAnimation) {
|
||||
activeWeapon.playAnimation(this.activeAnimation);
|
||||
this.meshWeapon.setAnimationTime(this.activeAnimation, this.meshBody.getAnimationTime(this.activeAnimation));
|
||||
}
|
||||
}
|
||||
}
|
||||
setAnimation(animationName) {
|
||||
if (animationName === this.activeAnimation || !animationName)
|
||||
return;
|
||||
if (this.meshBody) {
|
||||
this.meshBody.setAnimationWeight(animationName, 0);
|
||||
this.meshBody.playAnimation(animationName);
|
||||
this.oldAnimation = this.activeAnimation;
|
||||
this.activeAnimation = animationName;
|
||||
this.blendCounter = this.transitionFrames;
|
||||
}
|
||||
if (this.meshWeapon) {
|
||||
this.meshWeapon.setAnimationWeight(animationName, 0);
|
||||
this.meshWeapon.playAnimation(animationName);
|
||||
}
|
||||
}
|
||||
update(delta) {
|
||||
if (this.controls)
|
||||
this.updateMovementModel(delta);
|
||||
if (this.animations) {
|
||||
this.updateBehaviors();
|
||||
this.updateAnimations(delta);
|
||||
}
|
||||
}
|
||||
updateAnimations(delta) {
|
||||
let mix = 1;
|
||||
if (this.blendCounter > 0) {
|
||||
mix = (this.transitionFrames - this.blendCounter) / this.transitionFrames;
|
||||
this.blendCounter -= 1;
|
||||
}
|
||||
if (this.meshBody) {
|
||||
this.meshBody.update(delta);
|
||||
this.meshBody.setAnimationWeight(this.activeAnimation, mix);
|
||||
this.meshBody.setAnimationWeight(this.oldAnimation, 1 - mix);
|
||||
}
|
||||
if (this.meshWeapon) {
|
||||
this.meshWeapon.update(delta);
|
||||
this.meshWeapon.setAnimationWeight(this.activeAnimation, mix);
|
||||
this.meshWeapon.setAnimationWeight(this.oldAnimation, 1 - mix);
|
||||
}
|
||||
}
|
||||
updateBehaviors() {
|
||||
const controls = this.controls;
|
||||
const animations = this.animations;
|
||||
let moveAnimation, idleAnimation;
|
||||
if (controls.crouch) {
|
||||
moveAnimation = animations["crouchMove"];
|
||||
idleAnimation = animations["crouchIdle"];
|
||||
} else {
|
||||
moveAnimation = animations["move"];
|
||||
idleAnimation = animations["idle"];
|
||||
}
|
||||
if (controls.jump) {
|
||||
moveAnimation = animations["jump"];
|
||||
idleAnimation = animations["jump"];
|
||||
}
|
||||
if (controls.attack) {
|
||||
if (controls.crouch) {
|
||||
moveAnimation = animations["crouchAttack"];
|
||||
idleAnimation = animations["crouchAttack"];
|
||||
} else {
|
||||
moveAnimation = animations["attack"];
|
||||
idleAnimation = animations["attack"];
|
||||
}
|
||||
}
|
||||
if (controls.moveForward || controls.moveBackward || controls.moveLeft || controls.moveRight) {
|
||||
if (this.activeAnimation !== moveAnimation) {
|
||||
this.setAnimation(moveAnimation);
|
||||
}
|
||||
}
|
||||
if (Math.abs(this.speed) < 0.2 * this.maxSpeed && !(controls.moveLeft || controls.moveRight || controls.moveForward || controls.moveBackward)) {
|
||||
if (this.activeAnimation !== idleAnimation) {
|
||||
this.setAnimation(idleAnimation);
|
||||
}
|
||||
}
|
||||
if (controls.moveForward) {
|
||||
if (this.meshBody) {
|
||||
this.meshBody.setAnimationDirectionForward(this.activeAnimation);
|
||||
this.meshBody.setAnimationDirectionForward(this.oldAnimation);
|
||||
}
|
||||
if (this.meshWeapon) {
|
||||
this.meshWeapon.setAnimationDirectionForward(this.activeAnimation);
|
||||
this.meshWeapon.setAnimationDirectionForward(this.oldAnimation);
|
||||
}
|
||||
}
|
||||
if (controls.moveBackward) {
|
||||
if (this.meshBody) {
|
||||
this.meshBody.setAnimationDirectionBackward(this.activeAnimation);
|
||||
this.meshBody.setAnimationDirectionBackward(this.oldAnimation);
|
||||
}
|
||||
if (this.meshWeapon) {
|
||||
this.meshWeapon.setAnimationDirectionBackward(this.activeAnimation);
|
||||
this.meshWeapon.setAnimationDirectionBackward(this.oldAnimation);
|
||||
}
|
||||
}
|
||||
}
|
||||
updateMovementModel(delta) {
|
||||
function exponentialEaseOut(k) {
|
||||
return k === 1 ? 1 : -Math.pow(2, -10 * k) + 1;
|
||||
}
|
||||
const controls = this.controls;
|
||||
if (controls.crouch)
|
||||
this.maxSpeed = this.crouchSpeed;
|
||||
else
|
||||
this.maxSpeed = this.walkSpeed;
|
||||
this.maxReverseSpeed = -this.maxSpeed;
|
||||
if (controls.moveForward)
|
||||
this.speed = THREE.MathUtils.clamp(this.speed + delta * this.frontAcceleration, this.maxReverseSpeed, this.maxSpeed);
|
||||
if (controls.moveBackward)
|
||||
this.speed = THREE.MathUtils.clamp(this.speed - delta * this.backAcceleration, this.maxReverseSpeed, this.maxSpeed);
|
||||
const dir = 1;
|
||||
if (controls.moveLeft) {
|
||||
this.bodyOrientation += delta * this.angularSpeed;
|
||||
this.speed = THREE.MathUtils.clamp(
|
||||
this.speed + dir * delta * this.frontAcceleration,
|
||||
this.maxReverseSpeed,
|
||||
this.maxSpeed
|
||||
);
|
||||
}
|
||||
if (controls.moveRight) {
|
||||
this.bodyOrientation -= delta * this.angularSpeed;
|
||||
this.speed = THREE.MathUtils.clamp(
|
||||
this.speed + dir * delta * this.frontAcceleration,
|
||||
this.maxReverseSpeed,
|
||||
this.maxSpeed
|
||||
);
|
||||
}
|
||||
if (!(controls.moveForward || controls.moveBackward)) {
|
||||
if (this.speed > 0) {
|
||||
const k = exponentialEaseOut(this.speed / this.maxSpeed);
|
||||
this.speed = THREE.MathUtils.clamp(this.speed - k * delta * this.frontDecceleration, 0, this.maxSpeed);
|
||||
} else {
|
||||
const k = exponentialEaseOut(this.speed / this.maxReverseSpeed);
|
||||
this.speed = THREE.MathUtils.clamp(this.speed + k * delta * this.backAcceleration, this.maxReverseSpeed, 0);
|
||||
}
|
||||
}
|
||||
const forwardDelta = this.speed * delta;
|
||||
this.root.position.x += Math.sin(this.bodyOrientation) * forwardDelta;
|
||||
this.root.position.z += Math.cos(this.bodyOrientation) * forwardDelta;
|
||||
this.root.rotation.y = this.bodyOrientation;
|
||||
}
|
||||
// internal
|
||||
_createPart(geometry, skinMap) {
|
||||
const materialWireframe = new THREE.MeshLambertMaterial({
|
||||
color: 16755200,
|
||||
wireframe: true,
|
||||
morphTargets: true,
|
||||
morphNormals: true
|
||||
});
|
||||
const materialTexture = new THREE.MeshLambertMaterial({
|
||||
color: 16777215,
|
||||
wireframe: false,
|
||||
map: skinMap,
|
||||
morphTargets: true,
|
||||
morphNormals: true
|
||||
});
|
||||
const mesh = new MorphBlendMesh.MorphBlendMesh(geometry, materialTexture);
|
||||
mesh.rotation.y = -Math.PI / 2;
|
||||
mesh.materialTexture = materialTexture;
|
||||
mesh.materialWireframe = materialWireframe;
|
||||
mesh.autoCreateAnimations(this.animationFPS);
|
||||
return mesh;
|
||||
}
|
||||
}
|
||||
exports.MD2CharacterComplex = MD2CharacterComplex;
|
||||
//# sourceMappingURL=MD2CharacterComplex.cjs.map
|
||||
1
node_modules/three-stdlib/misc/MD2CharacterComplex.cjs.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/MD2CharacterComplex.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
47
node_modules/three-stdlib/misc/MD2CharacterComplex.d.ts
generated
vendored
Normal file
47
node_modules/three-stdlib/misc/MD2CharacterComplex.d.ts
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
import { Object3D, Mesh, Texture } from 'three'
|
||||
|
||||
export class MD2CharacterComplex {
|
||||
constructor()
|
||||
scale: number
|
||||
animationFPS: number
|
||||
transitionFrames: number
|
||||
maxSpeed: number
|
||||
maxReverseSpeed: number
|
||||
frontAcceleration: number
|
||||
backAcceleration: number
|
||||
frontDecceleration: number
|
||||
angularSpeed: number
|
||||
root: Object3D
|
||||
meshBody: Mesh | null
|
||||
meshWeapon: Mesh | null
|
||||
controls: null
|
||||
skinsBody: Texture[]
|
||||
skinsWeapon: Texture[]
|
||||
weapons: Mesh[]
|
||||
currentSkin: number
|
||||
onLoadComplete: () => void
|
||||
|
||||
meshes: Mesh[]
|
||||
animations: object[]
|
||||
loadCounter: number
|
||||
speed: number
|
||||
bodyOrientation: number
|
||||
walkSpeed: number
|
||||
crouchSpeed: number
|
||||
activeAnimation: string
|
||||
oldAnimation: string
|
||||
|
||||
enableShadows(enable: boolean): void
|
||||
setVisible(enable: boolean): void
|
||||
shareParts(original: MD2CharacterComplex): void
|
||||
loadParts(config: object): void
|
||||
setPlaybackRate(rate: number): void
|
||||
setWireframe(wireframeEnabled: boolean): void
|
||||
setSkin(index: number): void
|
||||
setWeapon(index: number): void
|
||||
setAnimation(animationName: string): void
|
||||
update(delta: number): void
|
||||
updateAnimations(delta: number): void
|
||||
updateBehaviors(): void
|
||||
updateMovementModel(delta: number): void
|
||||
}
|
||||
333
node_modules/three-stdlib/misc/MD2CharacterComplex.js
generated
vendored
Normal file
333
node_modules/three-stdlib/misc/MD2CharacterComplex.js
generated
vendored
Normal file
@@ -0,0 +1,333 @@
|
||||
import { Object3D, Box3, MathUtils, MeshLambertMaterial, TextureLoader, UVMapping } from "three";
|
||||
import { MD2Loader } from "../loaders/MD2Loader.js";
|
||||
import { MorphBlendMesh } from "./MorphBlendMesh.js";
|
||||
class MD2CharacterComplex {
|
||||
constructor() {
|
||||
this.scale = 1;
|
||||
this.animationFPS = 6;
|
||||
this.transitionFrames = 15;
|
||||
this.maxSpeed = 275;
|
||||
this.maxReverseSpeed = -275;
|
||||
this.frontAcceleration = 600;
|
||||
this.backAcceleration = 600;
|
||||
this.frontDecceleration = 600;
|
||||
this.angularSpeed = 2.5;
|
||||
this.root = new Object3D();
|
||||
this.meshBody = null;
|
||||
this.meshWeapon = null;
|
||||
this.controls = null;
|
||||
this.skinsBody = [];
|
||||
this.skinsWeapon = [];
|
||||
this.weapons = [];
|
||||
this.currentSkin = void 0;
|
||||
this.onLoadComplete = function() {
|
||||
};
|
||||
this.meshes = [];
|
||||
this.animations = {};
|
||||
this.loadCounter = 0;
|
||||
this.speed = 0;
|
||||
this.bodyOrientation = 0;
|
||||
this.walkSpeed = this.maxSpeed;
|
||||
this.crouchSpeed = this.maxSpeed * 0.5;
|
||||
this.activeAnimation = null;
|
||||
this.oldAnimation = null;
|
||||
}
|
||||
enableShadows(enable) {
|
||||
for (let i = 0; i < this.meshes.length; i++) {
|
||||
this.meshes[i].castShadow = enable;
|
||||
this.meshes[i].receiveShadow = enable;
|
||||
}
|
||||
}
|
||||
setVisible(enable) {
|
||||
for (let i = 0; i < this.meshes.length; i++) {
|
||||
this.meshes[i].visible = enable;
|
||||
this.meshes[i].visible = enable;
|
||||
}
|
||||
}
|
||||
shareParts(original) {
|
||||
this.animations = original.animations;
|
||||
this.walkSpeed = original.walkSpeed;
|
||||
this.crouchSpeed = original.crouchSpeed;
|
||||
this.skinsBody = original.skinsBody;
|
||||
this.skinsWeapon = original.skinsWeapon;
|
||||
const mesh = this._createPart(original.meshBody.geometry, this.skinsBody[0]);
|
||||
mesh.scale.set(this.scale, this.scale, this.scale);
|
||||
this.root.position.y = original.root.position.y;
|
||||
this.root.add(mesh);
|
||||
this.meshBody = mesh;
|
||||
this.meshes.push(mesh);
|
||||
for (let i = 0; i < original.weapons.length; i++) {
|
||||
const meshWeapon = this._createPart(original.weapons[i].geometry, this.skinsWeapon[i]);
|
||||
meshWeapon.scale.set(this.scale, this.scale, this.scale);
|
||||
meshWeapon.visible = false;
|
||||
meshWeapon.name = original.weapons[i].name;
|
||||
this.root.add(meshWeapon);
|
||||
this.weapons[i] = meshWeapon;
|
||||
this.meshWeapon = meshWeapon;
|
||||
this.meshes.push(meshWeapon);
|
||||
}
|
||||
}
|
||||
loadParts(config) {
|
||||
const scope = this;
|
||||
function loadTextures(baseUrl, textureUrls) {
|
||||
const textureLoader = new TextureLoader();
|
||||
const textures = [];
|
||||
for (let i = 0; i < textureUrls.length; i++) {
|
||||
textures[i] = textureLoader.load(baseUrl + textureUrls[i], checkLoadingComplete);
|
||||
textures[i].mapping = UVMapping;
|
||||
textures[i].name = textureUrls[i];
|
||||
if ("colorSpace" in textures[i])
|
||||
textures[i].colorSpace = "srgb";
|
||||
else
|
||||
textures[i].encoding = 3001;
|
||||
}
|
||||
return textures;
|
||||
}
|
||||
function checkLoadingComplete() {
|
||||
scope.loadCounter -= 1;
|
||||
if (scope.loadCounter === 0)
|
||||
scope.onLoadComplete();
|
||||
}
|
||||
this.animations = config.animations;
|
||||
this.walkSpeed = config.walkSpeed;
|
||||
this.crouchSpeed = config.crouchSpeed;
|
||||
this.loadCounter = config.weapons.length * 2 + config.skins.length + 1;
|
||||
const weaponsTextures = [];
|
||||
for (let i = 0; i < config.weapons.length; i++)
|
||||
weaponsTextures[i] = config.weapons[i][1];
|
||||
this.skinsBody = loadTextures(config.baseUrl + "skins/", config.skins);
|
||||
this.skinsWeapon = loadTextures(config.baseUrl + "skins/", weaponsTextures);
|
||||
const loader = new MD2Loader();
|
||||
loader.load(config.baseUrl + config.body, function(geo) {
|
||||
const boundingBox = new Box3();
|
||||
boundingBox.setFromBufferAttribute(geo.attributes.position);
|
||||
scope.root.position.y = -scope.scale * boundingBox.min.y;
|
||||
const mesh = scope._createPart(geo, scope.skinsBody[0]);
|
||||
mesh.scale.set(scope.scale, scope.scale, scope.scale);
|
||||
scope.root.add(mesh);
|
||||
scope.meshBody = mesh;
|
||||
scope.meshes.push(mesh);
|
||||
checkLoadingComplete();
|
||||
});
|
||||
const generateCallback = function(index, name) {
|
||||
return function(geo) {
|
||||
const mesh = scope._createPart(geo, scope.skinsWeapon[index]);
|
||||
mesh.scale.set(scope.scale, scope.scale, scope.scale);
|
||||
mesh.visible = false;
|
||||
mesh.name = name;
|
||||
scope.root.add(mesh);
|
||||
scope.weapons[index] = mesh;
|
||||
scope.meshWeapon = mesh;
|
||||
scope.meshes.push(mesh);
|
||||
checkLoadingComplete();
|
||||
};
|
||||
};
|
||||
for (let i = 0; i < config.weapons.length; i++) {
|
||||
loader.load(config.baseUrl + config.weapons[i][0], generateCallback(i, config.weapons[i][0]));
|
||||
}
|
||||
}
|
||||
setPlaybackRate(rate) {
|
||||
if (this.meshBody)
|
||||
this.meshBody.duration = this.meshBody.baseDuration / rate;
|
||||
if (this.meshWeapon)
|
||||
this.meshWeapon.duration = this.meshWeapon.baseDuration / rate;
|
||||
}
|
||||
setWireframe(wireframeEnabled) {
|
||||
if (wireframeEnabled) {
|
||||
if (this.meshBody)
|
||||
this.meshBody.material = this.meshBody.materialWireframe;
|
||||
if (this.meshWeapon)
|
||||
this.meshWeapon.material = this.meshWeapon.materialWireframe;
|
||||
} else {
|
||||
if (this.meshBody)
|
||||
this.meshBody.material = this.meshBody.materialTexture;
|
||||
if (this.meshWeapon)
|
||||
this.meshWeapon.material = this.meshWeapon.materialTexture;
|
||||
}
|
||||
}
|
||||
setSkin(index) {
|
||||
if (this.meshBody && this.meshBody.material.wireframe === false) {
|
||||
this.meshBody.material.map = this.skinsBody[index];
|
||||
this.currentSkin = index;
|
||||
}
|
||||
}
|
||||
setWeapon(index) {
|
||||
for (let i = 0; i < this.weapons.length; i++)
|
||||
this.weapons[i].visible = false;
|
||||
const activeWeapon = this.weapons[index];
|
||||
if (activeWeapon) {
|
||||
activeWeapon.visible = true;
|
||||
this.meshWeapon = activeWeapon;
|
||||
if (this.activeAnimation) {
|
||||
activeWeapon.playAnimation(this.activeAnimation);
|
||||
this.meshWeapon.setAnimationTime(this.activeAnimation, this.meshBody.getAnimationTime(this.activeAnimation));
|
||||
}
|
||||
}
|
||||
}
|
||||
setAnimation(animationName) {
|
||||
if (animationName === this.activeAnimation || !animationName)
|
||||
return;
|
||||
if (this.meshBody) {
|
||||
this.meshBody.setAnimationWeight(animationName, 0);
|
||||
this.meshBody.playAnimation(animationName);
|
||||
this.oldAnimation = this.activeAnimation;
|
||||
this.activeAnimation = animationName;
|
||||
this.blendCounter = this.transitionFrames;
|
||||
}
|
||||
if (this.meshWeapon) {
|
||||
this.meshWeapon.setAnimationWeight(animationName, 0);
|
||||
this.meshWeapon.playAnimation(animationName);
|
||||
}
|
||||
}
|
||||
update(delta) {
|
||||
if (this.controls)
|
||||
this.updateMovementModel(delta);
|
||||
if (this.animations) {
|
||||
this.updateBehaviors();
|
||||
this.updateAnimations(delta);
|
||||
}
|
||||
}
|
||||
updateAnimations(delta) {
|
||||
let mix = 1;
|
||||
if (this.blendCounter > 0) {
|
||||
mix = (this.transitionFrames - this.blendCounter) / this.transitionFrames;
|
||||
this.blendCounter -= 1;
|
||||
}
|
||||
if (this.meshBody) {
|
||||
this.meshBody.update(delta);
|
||||
this.meshBody.setAnimationWeight(this.activeAnimation, mix);
|
||||
this.meshBody.setAnimationWeight(this.oldAnimation, 1 - mix);
|
||||
}
|
||||
if (this.meshWeapon) {
|
||||
this.meshWeapon.update(delta);
|
||||
this.meshWeapon.setAnimationWeight(this.activeAnimation, mix);
|
||||
this.meshWeapon.setAnimationWeight(this.oldAnimation, 1 - mix);
|
||||
}
|
||||
}
|
||||
updateBehaviors() {
|
||||
const controls = this.controls;
|
||||
const animations = this.animations;
|
||||
let moveAnimation, idleAnimation;
|
||||
if (controls.crouch) {
|
||||
moveAnimation = animations["crouchMove"];
|
||||
idleAnimation = animations["crouchIdle"];
|
||||
} else {
|
||||
moveAnimation = animations["move"];
|
||||
idleAnimation = animations["idle"];
|
||||
}
|
||||
if (controls.jump) {
|
||||
moveAnimation = animations["jump"];
|
||||
idleAnimation = animations["jump"];
|
||||
}
|
||||
if (controls.attack) {
|
||||
if (controls.crouch) {
|
||||
moveAnimation = animations["crouchAttack"];
|
||||
idleAnimation = animations["crouchAttack"];
|
||||
} else {
|
||||
moveAnimation = animations["attack"];
|
||||
idleAnimation = animations["attack"];
|
||||
}
|
||||
}
|
||||
if (controls.moveForward || controls.moveBackward || controls.moveLeft || controls.moveRight) {
|
||||
if (this.activeAnimation !== moveAnimation) {
|
||||
this.setAnimation(moveAnimation);
|
||||
}
|
||||
}
|
||||
if (Math.abs(this.speed) < 0.2 * this.maxSpeed && !(controls.moveLeft || controls.moveRight || controls.moveForward || controls.moveBackward)) {
|
||||
if (this.activeAnimation !== idleAnimation) {
|
||||
this.setAnimation(idleAnimation);
|
||||
}
|
||||
}
|
||||
if (controls.moveForward) {
|
||||
if (this.meshBody) {
|
||||
this.meshBody.setAnimationDirectionForward(this.activeAnimation);
|
||||
this.meshBody.setAnimationDirectionForward(this.oldAnimation);
|
||||
}
|
||||
if (this.meshWeapon) {
|
||||
this.meshWeapon.setAnimationDirectionForward(this.activeAnimation);
|
||||
this.meshWeapon.setAnimationDirectionForward(this.oldAnimation);
|
||||
}
|
||||
}
|
||||
if (controls.moveBackward) {
|
||||
if (this.meshBody) {
|
||||
this.meshBody.setAnimationDirectionBackward(this.activeAnimation);
|
||||
this.meshBody.setAnimationDirectionBackward(this.oldAnimation);
|
||||
}
|
||||
if (this.meshWeapon) {
|
||||
this.meshWeapon.setAnimationDirectionBackward(this.activeAnimation);
|
||||
this.meshWeapon.setAnimationDirectionBackward(this.oldAnimation);
|
||||
}
|
||||
}
|
||||
}
|
||||
updateMovementModel(delta) {
|
||||
function exponentialEaseOut(k) {
|
||||
return k === 1 ? 1 : -Math.pow(2, -10 * k) + 1;
|
||||
}
|
||||
const controls = this.controls;
|
||||
if (controls.crouch)
|
||||
this.maxSpeed = this.crouchSpeed;
|
||||
else
|
||||
this.maxSpeed = this.walkSpeed;
|
||||
this.maxReverseSpeed = -this.maxSpeed;
|
||||
if (controls.moveForward)
|
||||
this.speed = MathUtils.clamp(this.speed + delta * this.frontAcceleration, this.maxReverseSpeed, this.maxSpeed);
|
||||
if (controls.moveBackward)
|
||||
this.speed = MathUtils.clamp(this.speed - delta * this.backAcceleration, this.maxReverseSpeed, this.maxSpeed);
|
||||
const dir = 1;
|
||||
if (controls.moveLeft) {
|
||||
this.bodyOrientation += delta * this.angularSpeed;
|
||||
this.speed = MathUtils.clamp(
|
||||
this.speed + dir * delta * this.frontAcceleration,
|
||||
this.maxReverseSpeed,
|
||||
this.maxSpeed
|
||||
);
|
||||
}
|
||||
if (controls.moveRight) {
|
||||
this.bodyOrientation -= delta * this.angularSpeed;
|
||||
this.speed = MathUtils.clamp(
|
||||
this.speed + dir * delta * this.frontAcceleration,
|
||||
this.maxReverseSpeed,
|
||||
this.maxSpeed
|
||||
);
|
||||
}
|
||||
if (!(controls.moveForward || controls.moveBackward)) {
|
||||
if (this.speed > 0) {
|
||||
const k = exponentialEaseOut(this.speed / this.maxSpeed);
|
||||
this.speed = MathUtils.clamp(this.speed - k * delta * this.frontDecceleration, 0, this.maxSpeed);
|
||||
} else {
|
||||
const k = exponentialEaseOut(this.speed / this.maxReverseSpeed);
|
||||
this.speed = MathUtils.clamp(this.speed + k * delta * this.backAcceleration, this.maxReverseSpeed, 0);
|
||||
}
|
||||
}
|
||||
const forwardDelta = this.speed * delta;
|
||||
this.root.position.x += Math.sin(this.bodyOrientation) * forwardDelta;
|
||||
this.root.position.z += Math.cos(this.bodyOrientation) * forwardDelta;
|
||||
this.root.rotation.y = this.bodyOrientation;
|
||||
}
|
||||
// internal
|
||||
_createPart(geometry, skinMap) {
|
||||
const materialWireframe = new MeshLambertMaterial({
|
||||
color: 16755200,
|
||||
wireframe: true,
|
||||
morphTargets: true,
|
||||
morphNormals: true
|
||||
});
|
||||
const materialTexture = new MeshLambertMaterial({
|
||||
color: 16777215,
|
||||
wireframe: false,
|
||||
map: skinMap,
|
||||
morphTargets: true,
|
||||
morphNormals: true
|
||||
});
|
||||
const mesh = new MorphBlendMesh(geometry, materialTexture);
|
||||
mesh.rotation.y = -Math.PI / 2;
|
||||
mesh.materialTexture = materialTexture;
|
||||
mesh.materialWireframe = materialWireframe;
|
||||
mesh.autoCreateAnimations(this.animationFPS);
|
||||
return mesh;
|
||||
}
|
||||
}
|
||||
export {
|
||||
MD2CharacterComplex
|
||||
};
|
||||
//# sourceMappingURL=MD2CharacterComplex.js.map
|
||||
1
node_modules/three-stdlib/misc/MD2CharacterComplex.js.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/MD2CharacterComplex.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
41
node_modules/three-stdlib/misc/MorphAnimMesh.cjs
generated
vendored
Normal file
41
node_modules/three-stdlib/misc/MorphAnimMesh.cjs
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
||||
const THREE = require("three");
|
||||
class MorphAnimMesh extends THREE.Mesh {
|
||||
constructor(geometry, material) {
|
||||
super(geometry, material);
|
||||
this.type = "MorphAnimMesh";
|
||||
this.mixer = new THREE.AnimationMixer(this);
|
||||
this.activeAction = null;
|
||||
}
|
||||
setDirectionForward() {
|
||||
this.mixer.timeScale = 1;
|
||||
}
|
||||
setDirectionBackward() {
|
||||
this.mixer.timeScale = -1;
|
||||
}
|
||||
playAnimation(label, fps) {
|
||||
if (this.activeAction) {
|
||||
this.activeAction.stop();
|
||||
this.activeAction = null;
|
||||
}
|
||||
const clip = THREE.AnimationClip.findByName(this, label);
|
||||
if (clip) {
|
||||
const action = this.mixer.clipAction(clip);
|
||||
action.timeScale = clip.tracks.length * fps / clip.duration;
|
||||
this.activeAction = action.play();
|
||||
} else {
|
||||
throw new Error("THREE.MorphAnimMesh: animations[" + label + "] undefined in .playAnimation()");
|
||||
}
|
||||
}
|
||||
updateAnimation(delta) {
|
||||
this.mixer.update(delta);
|
||||
}
|
||||
copy(source, recursive) {
|
||||
super.copy(source, recursive);
|
||||
this.mixer = new THREE.AnimationMixer(this);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
exports.MorphAnimMesh = MorphAnimMesh;
|
||||
//# sourceMappingURL=MorphAnimMesh.cjs.map
|
||||
1
node_modules/three-stdlib/misc/MorphAnimMesh.cjs.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/MorphAnimMesh.cjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"MorphAnimMesh.cjs","sources":["../../src/misc/MorphAnimMesh.js"],"sourcesContent":["import { AnimationClip, AnimationMixer, Mesh } from 'three'\n\nclass MorphAnimMesh extends Mesh {\n constructor(geometry, material) {\n super(geometry, material)\n\n this.type = 'MorphAnimMesh'\n\n this.mixer = new AnimationMixer(this)\n this.activeAction = null\n }\n\n setDirectionForward() {\n this.mixer.timeScale = 1.0\n }\n\n setDirectionBackward() {\n this.mixer.timeScale = -1.0\n }\n\n playAnimation(label, fps) {\n if (this.activeAction) {\n this.activeAction.stop()\n this.activeAction = null\n }\n\n const clip = AnimationClip.findByName(this, label)\n\n if (clip) {\n const action = this.mixer.clipAction(clip)\n action.timeScale = (clip.tracks.length * fps) / clip.duration\n this.activeAction = action.play()\n } else {\n throw new Error('THREE.MorphAnimMesh: animations[' + label + '] undefined in .playAnimation()')\n }\n }\n\n updateAnimation(delta) {\n this.mixer.update(delta)\n }\n\n copy(source, recursive) {\n super.copy(source, recursive)\n\n this.mixer = new AnimationMixer(this)\n\n return this\n }\n}\n\nexport { MorphAnimMesh }\n"],"names":["Mesh","AnimationMixer","AnimationClip"],"mappings":";;;AAEA,MAAM,sBAAsBA,MAAAA,KAAK;AAAA,EAC/B,YAAY,UAAU,UAAU;AAC9B,UAAM,UAAU,QAAQ;AAExB,SAAK,OAAO;AAEZ,SAAK,QAAQ,IAAIC,MAAc,eAAC,IAAI;AACpC,SAAK,eAAe;AAAA,EACrB;AAAA,EAED,sBAAsB;AACpB,SAAK,MAAM,YAAY;AAAA,EACxB;AAAA,EAED,uBAAuB;AACrB,SAAK,MAAM,YAAY;AAAA,EACxB;AAAA,EAED,cAAc,OAAO,KAAK;AACxB,QAAI,KAAK,cAAc;AACrB,WAAK,aAAa,KAAM;AACxB,WAAK,eAAe;AAAA,IACrB;AAED,UAAM,OAAOC,MAAa,cAAC,WAAW,MAAM,KAAK;AAEjD,QAAI,MAAM;AACR,YAAM,SAAS,KAAK,MAAM,WAAW,IAAI;AACzC,aAAO,YAAa,KAAK,OAAO,SAAS,MAAO,KAAK;AACrD,WAAK,eAAe,OAAO,KAAM;AAAA,IACvC,OAAW;AACL,YAAM,IAAI,MAAM,qCAAqC,QAAQ,iCAAiC;AAAA,IAC/F;AAAA,EACF;AAAA,EAED,gBAAgB,OAAO;AACrB,SAAK,MAAM,OAAO,KAAK;AAAA,EACxB;AAAA,EAED,KAAK,QAAQ,WAAW;AACtB,UAAM,KAAK,QAAQ,SAAS;AAE5B,SAAK,QAAQ,IAAID,MAAc,eAAC,IAAI;AAEpC,WAAO;AAAA,EACR;AACH;;"}
|
||||
13
node_modules/three-stdlib/misc/MorphAnimMesh.d.ts
generated
vendored
Normal file
13
node_modules/three-stdlib/misc/MorphAnimMesh.d.ts
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import { AnimationAction, AnimationMixer, BufferGeometry, Material, Mesh } from 'three'
|
||||
|
||||
export class MorphAnimMesh extends Mesh {
|
||||
constructor(geometry: BufferGeometry, material: Material)
|
||||
mixer: AnimationMixer
|
||||
activeAction: AnimationAction | null
|
||||
|
||||
setDirectionForward(): void
|
||||
setDirectionBackward(): void
|
||||
playAnimation(label: string, fps: number): void
|
||||
updateAnimation(delta: number): void
|
||||
copy(source: MorphAnimMesh, recursive?: boolean): this
|
||||
}
|
||||
41
node_modules/three-stdlib/misc/MorphAnimMesh.js
generated
vendored
Normal file
41
node_modules/three-stdlib/misc/MorphAnimMesh.js
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
import { Mesh, AnimationMixer, AnimationClip } from "three";
|
||||
class MorphAnimMesh extends Mesh {
|
||||
constructor(geometry, material) {
|
||||
super(geometry, material);
|
||||
this.type = "MorphAnimMesh";
|
||||
this.mixer = new AnimationMixer(this);
|
||||
this.activeAction = null;
|
||||
}
|
||||
setDirectionForward() {
|
||||
this.mixer.timeScale = 1;
|
||||
}
|
||||
setDirectionBackward() {
|
||||
this.mixer.timeScale = -1;
|
||||
}
|
||||
playAnimation(label, fps) {
|
||||
if (this.activeAction) {
|
||||
this.activeAction.stop();
|
||||
this.activeAction = null;
|
||||
}
|
||||
const clip = AnimationClip.findByName(this, label);
|
||||
if (clip) {
|
||||
const action = this.mixer.clipAction(clip);
|
||||
action.timeScale = clip.tracks.length * fps / clip.duration;
|
||||
this.activeAction = action.play();
|
||||
} else {
|
||||
throw new Error("THREE.MorphAnimMesh: animations[" + label + "] undefined in .playAnimation()");
|
||||
}
|
||||
}
|
||||
updateAnimation(delta) {
|
||||
this.mixer.update(delta);
|
||||
}
|
||||
copy(source, recursive) {
|
||||
super.copy(source, recursive);
|
||||
this.mixer = new AnimationMixer(this);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
export {
|
||||
MorphAnimMesh
|
||||
};
|
||||
//# sourceMappingURL=MorphAnimMesh.js.map
|
||||
1
node_modules/three-stdlib/misc/MorphAnimMesh.js.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/MorphAnimMesh.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"MorphAnimMesh.js","sources":["../../src/misc/MorphAnimMesh.js"],"sourcesContent":["import { AnimationClip, AnimationMixer, Mesh } from 'three'\n\nclass MorphAnimMesh extends Mesh {\n constructor(geometry, material) {\n super(geometry, material)\n\n this.type = 'MorphAnimMesh'\n\n this.mixer = new AnimationMixer(this)\n this.activeAction = null\n }\n\n setDirectionForward() {\n this.mixer.timeScale = 1.0\n }\n\n setDirectionBackward() {\n this.mixer.timeScale = -1.0\n }\n\n playAnimation(label, fps) {\n if (this.activeAction) {\n this.activeAction.stop()\n this.activeAction = null\n }\n\n const clip = AnimationClip.findByName(this, label)\n\n if (clip) {\n const action = this.mixer.clipAction(clip)\n action.timeScale = (clip.tracks.length * fps) / clip.duration\n this.activeAction = action.play()\n } else {\n throw new Error('THREE.MorphAnimMesh: animations[' + label + '] undefined in .playAnimation()')\n }\n }\n\n updateAnimation(delta) {\n this.mixer.update(delta)\n }\n\n copy(source, recursive) {\n super.copy(source, recursive)\n\n this.mixer = new AnimationMixer(this)\n\n return this\n }\n}\n\nexport { MorphAnimMesh }\n"],"names":[],"mappings":";AAEA,MAAM,sBAAsB,KAAK;AAAA,EAC/B,YAAY,UAAU,UAAU;AAC9B,UAAM,UAAU,QAAQ;AAExB,SAAK,OAAO;AAEZ,SAAK,QAAQ,IAAI,eAAe,IAAI;AACpC,SAAK,eAAe;AAAA,EACrB;AAAA,EAED,sBAAsB;AACpB,SAAK,MAAM,YAAY;AAAA,EACxB;AAAA,EAED,uBAAuB;AACrB,SAAK,MAAM,YAAY;AAAA,EACxB;AAAA,EAED,cAAc,OAAO,KAAK;AACxB,QAAI,KAAK,cAAc;AACrB,WAAK,aAAa,KAAM;AACxB,WAAK,eAAe;AAAA,IACrB;AAED,UAAM,OAAO,cAAc,WAAW,MAAM,KAAK;AAEjD,QAAI,MAAM;AACR,YAAM,SAAS,KAAK,MAAM,WAAW,IAAI;AACzC,aAAO,YAAa,KAAK,OAAO,SAAS,MAAO,KAAK;AACrD,WAAK,eAAe,OAAO,KAAM;AAAA,IACvC,OAAW;AACL,YAAM,IAAI,MAAM,qCAAqC,QAAQ,iCAAiC;AAAA,IAC/F;AAAA,EACF;AAAA,EAED,gBAAgB,OAAO;AACrB,SAAK,MAAM,OAAO,KAAK;AAAA,EACxB;AAAA,EAED,KAAK,QAAQ,WAAW;AACtB,UAAM,KAAK,QAAQ,SAAS;AAE5B,SAAK,QAAQ,IAAI,eAAe,IAAI;AAEpC,WAAO;AAAA,EACR;AACH;"}
|
||||
180
node_modules/three-stdlib/misc/MorphBlendMesh.cjs
generated
vendored
Normal file
180
node_modules/three-stdlib/misc/MorphBlendMesh.cjs
generated
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
||||
const THREE = require("three");
|
||||
class MorphBlendMesh extends THREE.Mesh {
|
||||
constructor(geometry, material) {
|
||||
super(geometry, material);
|
||||
this.animationsMap = {};
|
||||
this.animationsList = [];
|
||||
const numFrames = Object.keys(this.morphTargetDictionary).length;
|
||||
const name = "__default";
|
||||
const startFrame = 0;
|
||||
const endFrame = numFrames - 1;
|
||||
const fps = numFrames / 1;
|
||||
this.createAnimation(name, startFrame, endFrame, fps);
|
||||
this.setAnimationWeight(name, 1);
|
||||
}
|
||||
createAnimation(name, start, end, fps) {
|
||||
const animation = {
|
||||
start,
|
||||
end,
|
||||
length: end - start + 1,
|
||||
fps,
|
||||
duration: (end - start) / fps,
|
||||
lastFrame: 0,
|
||||
currentFrame: 0,
|
||||
active: false,
|
||||
time: 0,
|
||||
direction: 1,
|
||||
weight: 1,
|
||||
directionBackwards: false,
|
||||
mirroredLoop: false
|
||||
};
|
||||
this.animationsMap[name] = animation;
|
||||
this.animationsList.push(animation);
|
||||
}
|
||||
autoCreateAnimations(fps) {
|
||||
const pattern = /([a-z]+)_?(\d+)/i;
|
||||
let firstAnimation;
|
||||
const frameRanges = {};
|
||||
let i = 0;
|
||||
for (const key in this.morphTargetDictionary) {
|
||||
const chunks = key.match(pattern);
|
||||
if (chunks && chunks.length > 1) {
|
||||
const name = chunks[1];
|
||||
if (!frameRanges[name])
|
||||
frameRanges[name] = { start: Infinity, end: -Infinity };
|
||||
const range = frameRanges[name];
|
||||
if (i < range.start)
|
||||
range.start = i;
|
||||
if (i > range.end)
|
||||
range.end = i;
|
||||
if (!firstAnimation)
|
||||
firstAnimation = name;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
for (const name in frameRanges) {
|
||||
const range = frameRanges[name];
|
||||
this.createAnimation(name, range.start, range.end, fps);
|
||||
}
|
||||
this.firstAnimation = firstAnimation;
|
||||
}
|
||||
setAnimationDirectionForward(name) {
|
||||
const animation = this.animationsMap[name];
|
||||
if (animation) {
|
||||
animation.direction = 1;
|
||||
animation.directionBackwards = false;
|
||||
}
|
||||
}
|
||||
setAnimationDirectionBackward(name) {
|
||||
const animation = this.animationsMap[name];
|
||||
if (animation) {
|
||||
animation.direction = -1;
|
||||
animation.directionBackwards = true;
|
||||
}
|
||||
}
|
||||
setAnimationFPS(name, fps) {
|
||||
const animation = this.animationsMap[name];
|
||||
if (animation) {
|
||||
animation.fps = fps;
|
||||
animation.duration = (animation.end - animation.start) / animation.fps;
|
||||
}
|
||||
}
|
||||
setAnimationDuration(name, duration) {
|
||||
const animation = this.animationsMap[name];
|
||||
if (animation) {
|
||||
animation.duration = duration;
|
||||
animation.fps = (animation.end - animation.start) / animation.duration;
|
||||
}
|
||||
}
|
||||
setAnimationWeight(name, weight) {
|
||||
const animation = this.animationsMap[name];
|
||||
if (animation) {
|
||||
animation.weight = weight;
|
||||
}
|
||||
}
|
||||
setAnimationTime(name, time) {
|
||||
const animation = this.animationsMap[name];
|
||||
if (animation) {
|
||||
animation.time = time;
|
||||
}
|
||||
}
|
||||
getAnimationTime(name) {
|
||||
let time = 0;
|
||||
const animation = this.animationsMap[name];
|
||||
if (animation) {
|
||||
time = animation.time;
|
||||
}
|
||||
return time;
|
||||
}
|
||||
getAnimationDuration(name) {
|
||||
let duration = -1;
|
||||
const animation = this.animationsMap[name];
|
||||
if (animation) {
|
||||
duration = animation.duration;
|
||||
}
|
||||
return duration;
|
||||
}
|
||||
playAnimation(name) {
|
||||
const animation = this.animationsMap[name];
|
||||
if (animation) {
|
||||
animation.time = 0;
|
||||
animation.active = true;
|
||||
} else {
|
||||
console.warn("THREE.MorphBlendMesh: animation[" + name + "] undefined in .playAnimation()");
|
||||
}
|
||||
}
|
||||
stopAnimation(name) {
|
||||
const animation = this.animationsMap[name];
|
||||
if (animation) {
|
||||
animation.active = false;
|
||||
}
|
||||
}
|
||||
update(delta) {
|
||||
for (let i = 0, il = this.animationsList.length; i < il; i++) {
|
||||
const animation = this.animationsList[i];
|
||||
if (!animation.active)
|
||||
continue;
|
||||
const frameTime = animation.duration / animation.length;
|
||||
animation.time += animation.direction * delta;
|
||||
if (animation.mirroredLoop) {
|
||||
if (animation.time > animation.duration || animation.time < 0) {
|
||||
animation.direction *= -1;
|
||||
if (animation.time > animation.duration) {
|
||||
animation.time = animation.duration;
|
||||
animation.directionBackwards = true;
|
||||
}
|
||||
if (animation.time < 0) {
|
||||
animation.time = 0;
|
||||
animation.directionBackwards = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
animation.time = animation.time % animation.duration;
|
||||
if (animation.time < 0)
|
||||
animation.time += animation.duration;
|
||||
}
|
||||
const keyframe = animation.start + THREE.MathUtils.clamp(Math.floor(animation.time / frameTime), 0, animation.length - 1);
|
||||
const weight = animation.weight;
|
||||
if (keyframe !== animation.currentFrame) {
|
||||
this.morphTargetInfluences[animation.lastFrame] = 0;
|
||||
this.morphTargetInfluences[animation.currentFrame] = 1 * weight;
|
||||
this.morphTargetInfluences[keyframe] = 0;
|
||||
animation.lastFrame = animation.currentFrame;
|
||||
animation.currentFrame = keyframe;
|
||||
}
|
||||
let mix = animation.time % frameTime / frameTime;
|
||||
if (animation.directionBackwards)
|
||||
mix = 1 - mix;
|
||||
if (animation.currentFrame !== animation.lastFrame) {
|
||||
this.morphTargetInfluences[animation.currentFrame] = mix * weight;
|
||||
this.morphTargetInfluences[animation.lastFrame] = (1 - mix) * weight;
|
||||
} else {
|
||||
this.morphTargetInfluences[animation.currentFrame] = weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.MorphBlendMesh = MorphBlendMesh;
|
||||
//# sourceMappingURL=MorphBlendMesh.cjs.map
|
||||
1
node_modules/three-stdlib/misc/MorphBlendMesh.cjs.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/MorphBlendMesh.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
21
node_modules/three-stdlib/misc/MorphBlendMesh.d.ts
generated
vendored
Normal file
21
node_modules/three-stdlib/misc/MorphBlendMesh.d.ts
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import { BufferGeometry, Material, Mesh } from 'three'
|
||||
|
||||
export class MorphBlendMesh extends Mesh {
|
||||
constructor(geometry: BufferGeometry, material: Material)
|
||||
animationsMap: object
|
||||
animationsList: object[]
|
||||
|
||||
createAnimation(name: string, start: number, end: number, fps: number): void
|
||||
autoCreateAnimations(fps: number): void
|
||||
setAnimationDirectionForward(name: string): void
|
||||
setAnimationDirectionBackward(name: string): void
|
||||
setAnimationFPS(name: string, fps: number): void
|
||||
setAnimationDuration(name: string, duration: number): void
|
||||
setAnimationWeight(name: string, weight: number): void
|
||||
setAnimationTime(name: string, time: number): void
|
||||
getAnimationTime(name: string): number
|
||||
getAnimationDuration(name: string): number
|
||||
playAnimation(name: string): void
|
||||
stopAnimation(name: string): void
|
||||
update(delta: number): void
|
||||
}
|
||||
180
node_modules/three-stdlib/misc/MorphBlendMesh.js
generated
vendored
Normal file
180
node_modules/three-stdlib/misc/MorphBlendMesh.js
generated
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
import { Mesh, MathUtils } from "three";
|
||||
class MorphBlendMesh extends Mesh {
|
||||
constructor(geometry, material) {
|
||||
super(geometry, material);
|
||||
this.animationsMap = {};
|
||||
this.animationsList = [];
|
||||
const numFrames = Object.keys(this.morphTargetDictionary).length;
|
||||
const name = "__default";
|
||||
const startFrame = 0;
|
||||
const endFrame = numFrames - 1;
|
||||
const fps = numFrames / 1;
|
||||
this.createAnimation(name, startFrame, endFrame, fps);
|
||||
this.setAnimationWeight(name, 1);
|
||||
}
|
||||
createAnimation(name, start, end, fps) {
|
||||
const animation = {
|
||||
start,
|
||||
end,
|
||||
length: end - start + 1,
|
||||
fps,
|
||||
duration: (end - start) / fps,
|
||||
lastFrame: 0,
|
||||
currentFrame: 0,
|
||||
active: false,
|
||||
time: 0,
|
||||
direction: 1,
|
||||
weight: 1,
|
||||
directionBackwards: false,
|
||||
mirroredLoop: false
|
||||
};
|
||||
this.animationsMap[name] = animation;
|
||||
this.animationsList.push(animation);
|
||||
}
|
||||
autoCreateAnimations(fps) {
|
||||
const pattern = /([a-z]+)_?(\d+)/i;
|
||||
let firstAnimation;
|
||||
const frameRanges = {};
|
||||
let i = 0;
|
||||
for (const key in this.morphTargetDictionary) {
|
||||
const chunks = key.match(pattern);
|
||||
if (chunks && chunks.length > 1) {
|
||||
const name = chunks[1];
|
||||
if (!frameRanges[name])
|
||||
frameRanges[name] = { start: Infinity, end: -Infinity };
|
||||
const range = frameRanges[name];
|
||||
if (i < range.start)
|
||||
range.start = i;
|
||||
if (i > range.end)
|
||||
range.end = i;
|
||||
if (!firstAnimation)
|
||||
firstAnimation = name;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
for (const name in frameRanges) {
|
||||
const range = frameRanges[name];
|
||||
this.createAnimation(name, range.start, range.end, fps);
|
||||
}
|
||||
this.firstAnimation = firstAnimation;
|
||||
}
|
||||
setAnimationDirectionForward(name) {
|
||||
const animation = this.animationsMap[name];
|
||||
if (animation) {
|
||||
animation.direction = 1;
|
||||
animation.directionBackwards = false;
|
||||
}
|
||||
}
|
||||
setAnimationDirectionBackward(name) {
|
||||
const animation = this.animationsMap[name];
|
||||
if (animation) {
|
||||
animation.direction = -1;
|
||||
animation.directionBackwards = true;
|
||||
}
|
||||
}
|
||||
setAnimationFPS(name, fps) {
|
||||
const animation = this.animationsMap[name];
|
||||
if (animation) {
|
||||
animation.fps = fps;
|
||||
animation.duration = (animation.end - animation.start) / animation.fps;
|
||||
}
|
||||
}
|
||||
setAnimationDuration(name, duration) {
|
||||
const animation = this.animationsMap[name];
|
||||
if (animation) {
|
||||
animation.duration = duration;
|
||||
animation.fps = (animation.end - animation.start) / animation.duration;
|
||||
}
|
||||
}
|
||||
setAnimationWeight(name, weight) {
|
||||
const animation = this.animationsMap[name];
|
||||
if (animation) {
|
||||
animation.weight = weight;
|
||||
}
|
||||
}
|
||||
setAnimationTime(name, time) {
|
||||
const animation = this.animationsMap[name];
|
||||
if (animation) {
|
||||
animation.time = time;
|
||||
}
|
||||
}
|
||||
getAnimationTime(name) {
|
||||
let time = 0;
|
||||
const animation = this.animationsMap[name];
|
||||
if (animation) {
|
||||
time = animation.time;
|
||||
}
|
||||
return time;
|
||||
}
|
||||
getAnimationDuration(name) {
|
||||
let duration = -1;
|
||||
const animation = this.animationsMap[name];
|
||||
if (animation) {
|
||||
duration = animation.duration;
|
||||
}
|
||||
return duration;
|
||||
}
|
||||
playAnimation(name) {
|
||||
const animation = this.animationsMap[name];
|
||||
if (animation) {
|
||||
animation.time = 0;
|
||||
animation.active = true;
|
||||
} else {
|
||||
console.warn("THREE.MorphBlendMesh: animation[" + name + "] undefined in .playAnimation()");
|
||||
}
|
||||
}
|
||||
stopAnimation(name) {
|
||||
const animation = this.animationsMap[name];
|
||||
if (animation) {
|
||||
animation.active = false;
|
||||
}
|
||||
}
|
||||
update(delta) {
|
||||
for (let i = 0, il = this.animationsList.length; i < il; i++) {
|
||||
const animation = this.animationsList[i];
|
||||
if (!animation.active)
|
||||
continue;
|
||||
const frameTime = animation.duration / animation.length;
|
||||
animation.time += animation.direction * delta;
|
||||
if (animation.mirroredLoop) {
|
||||
if (animation.time > animation.duration || animation.time < 0) {
|
||||
animation.direction *= -1;
|
||||
if (animation.time > animation.duration) {
|
||||
animation.time = animation.duration;
|
||||
animation.directionBackwards = true;
|
||||
}
|
||||
if (animation.time < 0) {
|
||||
animation.time = 0;
|
||||
animation.directionBackwards = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
animation.time = animation.time % animation.duration;
|
||||
if (animation.time < 0)
|
||||
animation.time += animation.duration;
|
||||
}
|
||||
const keyframe = animation.start + MathUtils.clamp(Math.floor(animation.time / frameTime), 0, animation.length - 1);
|
||||
const weight = animation.weight;
|
||||
if (keyframe !== animation.currentFrame) {
|
||||
this.morphTargetInfluences[animation.lastFrame] = 0;
|
||||
this.morphTargetInfluences[animation.currentFrame] = 1 * weight;
|
||||
this.morphTargetInfluences[keyframe] = 0;
|
||||
animation.lastFrame = animation.currentFrame;
|
||||
animation.currentFrame = keyframe;
|
||||
}
|
||||
let mix = animation.time % frameTime / frameTime;
|
||||
if (animation.directionBackwards)
|
||||
mix = 1 - mix;
|
||||
if (animation.currentFrame !== animation.lastFrame) {
|
||||
this.morphTargetInfluences[animation.currentFrame] = mix * weight;
|
||||
this.morphTargetInfluences[animation.lastFrame] = (1 - mix) * weight;
|
||||
} else {
|
||||
this.morphTargetInfluences[animation.currentFrame] = weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
export {
|
||||
MorphBlendMesh
|
||||
};
|
||||
//# sourceMappingURL=MorphBlendMesh.js.map
|
||||
1
node_modules/three-stdlib/misc/MorphBlendMesh.js.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/MorphBlendMesh.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
189
node_modules/three-stdlib/misc/ProgressiveLightmap.cjs
generated
vendored
Normal file
189
node_modules/three-stdlib/misc/ProgressiveLightmap.cjs
generated
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
||||
const THREE = require("three");
|
||||
const potpack = require("potpack");
|
||||
const uv1 = require("../_polyfill/uv1.cjs");
|
||||
class ProgressiveLightMap {
|
||||
constructor(renderer, res = 1024) {
|
||||
this.renderer = renderer;
|
||||
this.res = res;
|
||||
this.lightMapContainers = [];
|
||||
this.compiled = false;
|
||||
this.scene = new THREE.Scene();
|
||||
this.scene.background = null;
|
||||
this.tinyTarget = new THREE.WebGLRenderTarget(1, 1);
|
||||
this.buffer1Active = false;
|
||||
this.firstUpdate = true;
|
||||
this.warned = false;
|
||||
const format = /(Android|iPad|iPhone|iPod)/g.test(navigator.userAgent) ? alfFloatType : THREE.FloatType;
|
||||
this.progressiveLightMap1 = new THREE.WebGLRenderTarget(this.res, this.res, { type: format });
|
||||
this.progressiveLightMap2 = new THREE.WebGLRenderTarget(this.res, this.res, { type: format });
|
||||
this.uvMat = new THREE.MeshPhongMaterial();
|
||||
this.uvMat.uniforms = {};
|
||||
this.uvMat.onBeforeCompile = (shader) => {
|
||||
shader.vertexShader = "#define USE_LIGHTMAP\n" + shader.vertexShader.slice(0, -1) + ` gl_Position = vec4((${uv1.UV1} - 0.5) * 2.0, 1.0, 1.0); }`;
|
||||
const bodyStart = shader.fragmentShader.indexOf("void main() {");
|
||||
shader.fragmentShader = `varying vec2 v${uv1.UV1 === "uv1" ? uv1.UV1 : "Uv2"};
|
||||
` + shader.fragmentShader.slice(0, bodyStart) + " uniform sampler2D previousShadowMap;\n uniform float averagingWindow;\n" + shader.fragmentShader.slice(bodyStart - 1, -1) + `
|
||||
vec3 texelOld = texture2D(previousShadowMap, v${uv1.UV1 === "uv1" ? uv1.UV1 : "Uv2"}).rgb;
|
||||
gl_FragColor.rgb = mix(texelOld, gl_FragColor.rgb, 1.0/averagingWindow);
|
||||
}`;
|
||||
shader.uniforms.previousShadowMap = { value: this.progressiveLightMap1.texture };
|
||||
shader.uniforms.averagingWindow = { value: 100 };
|
||||
this.uvMat.uniforms = shader.uniforms;
|
||||
this.uvMat.userData.shader = shader;
|
||||
this.compiled = true;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Sets these objects' materials' lightmaps and modifies their uv1's.
|
||||
* @param {Object3D} objects An array of objects and lights to set up your lightmap.
|
||||
*/
|
||||
addObjectsToLightMap(objects) {
|
||||
this.uv_boxes = [];
|
||||
const padding = 3 / this.res;
|
||||
for (let ob = 0; ob < objects.length; ob++) {
|
||||
const object = objects[ob];
|
||||
if (object.isLight) {
|
||||
this.scene.attach(object);
|
||||
continue;
|
||||
}
|
||||
if (!object.geometry.hasAttribute("uv")) {
|
||||
console.warn("All lightmap objects need UVs!");
|
||||
continue;
|
||||
}
|
||||
if (this.blurringPlane == null) {
|
||||
this._initializeBlurPlane(this.res, this.progressiveLightMap1);
|
||||
}
|
||||
object.material.lightMap = this.progressiveLightMap2.texture;
|
||||
object.material.dithering = true;
|
||||
object.castShadow = true;
|
||||
object.receiveShadow = true;
|
||||
object.renderOrder = 1e3 + ob;
|
||||
this.uv_boxes.push({ w: 1 + padding * 2, h: 1 + padding * 2, index: ob });
|
||||
this.lightMapContainers.push({ basicMat: object.material, object });
|
||||
this.compiled = false;
|
||||
}
|
||||
const dimensions = potpack(this.uv_boxes);
|
||||
this.uv_boxes.forEach((box) => {
|
||||
const uv1$1 = objects[box.index].geometry.getAttribute("uv").clone();
|
||||
for (let i = 0; i < uv1$1.array.length; i += uv1$1.itemSize) {
|
||||
uv1$1.array[i] = (uv1$1.array[i] + box.x + padding) / dimensions.w;
|
||||
uv1$1.array[i + 1] = (uv1$1.array[i + 1] + box.y + padding) / dimensions.h;
|
||||
}
|
||||
objects[box.index].geometry.setAttribute(uv1.UV1, uv1$1);
|
||||
objects[box.index].geometry.getAttribute(uv1.UV1).needsUpdate = true;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* This function renders each mesh one at a time into their respective surface maps
|
||||
* @param {Camera} camera Standard Rendering Camera
|
||||
* @param {number} blendWindow When >1, samples will accumulate over time.
|
||||
* @param {boolean} blurEdges Whether to fix UV Edges via blurring
|
||||
*/
|
||||
update(camera, blendWindow = 100, blurEdges = true) {
|
||||
if (this.blurringPlane == null) {
|
||||
return;
|
||||
}
|
||||
const oldTarget = this.renderer.getRenderTarget();
|
||||
this.blurringPlane.visible = blurEdges;
|
||||
for (let l = 0; l < this.lightMapContainers.length; l++) {
|
||||
this.lightMapContainers[l].object.oldScene = this.lightMapContainers[l].object.parent;
|
||||
this.scene.attach(this.lightMapContainers[l].object);
|
||||
}
|
||||
if (this.firstUpdate) {
|
||||
this.renderer.setRenderTarget(this.tinyTarget);
|
||||
this.renderer.render(this.scene, camera);
|
||||
this.firstUpdate = false;
|
||||
}
|
||||
for (let l = 0; l < this.lightMapContainers.length; l++) {
|
||||
this.uvMat.uniforms.averagingWindow = { value: blendWindow };
|
||||
this.lightMapContainers[l].object.material = this.uvMat;
|
||||
this.lightMapContainers[l].object.oldFrustumCulled = this.lightMapContainers[l].object.frustumCulled;
|
||||
this.lightMapContainers[l].object.frustumCulled = false;
|
||||
}
|
||||
const activeMap = this.buffer1Active ? this.progressiveLightMap1 : this.progressiveLightMap2;
|
||||
const inactiveMap = this.buffer1Active ? this.progressiveLightMap2 : this.progressiveLightMap1;
|
||||
this.renderer.setRenderTarget(activeMap);
|
||||
this.uvMat.uniforms.previousShadowMap = { value: inactiveMap.texture };
|
||||
this.blurringPlane.material.uniforms.previousShadowMap = { value: inactiveMap.texture };
|
||||
this.buffer1Active = !this.buffer1Active;
|
||||
this.renderer.render(this.scene, camera);
|
||||
for (let l = 0; l < this.lightMapContainers.length; l++) {
|
||||
this.lightMapContainers[l].object.frustumCulled = this.lightMapContainers[l].object.oldFrustumCulled;
|
||||
this.lightMapContainers[l].object.material = this.lightMapContainers[l].basicMat;
|
||||
this.lightMapContainers[l].object.oldScene.attach(this.lightMapContainers[l].object);
|
||||
}
|
||||
this.renderer.setRenderTarget(oldTarget);
|
||||
}
|
||||
/** DEBUG
|
||||
* Draw the lightmap in the main scene. Call this after adding the objects to it.
|
||||
* @param {boolean} visible Whether the debug plane should be visible
|
||||
* @param {Vector3} position Where the debug plane should be drawn
|
||||
*/
|
||||
showDebugLightmap(visible, position = void 0) {
|
||||
if (this.lightMapContainers.length == 0) {
|
||||
if (!this.warned) {
|
||||
console.warn("Call this after adding the objects!");
|
||||
this.warned = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (this.labelMesh == null) {
|
||||
this.labelMaterial = new THREE.MeshBasicMaterial({
|
||||
map: this.progressiveLightMap1.texture,
|
||||
side: THREE.DoubleSide
|
||||
});
|
||||
this.labelPlane = new THREE.PlaneGeometry(100, 100);
|
||||
this.labelMesh = new THREE.Mesh(this.labelPlane, this.labelMaterial);
|
||||
this.labelMesh.position.y = 250;
|
||||
this.lightMapContainers[0].object.parent.add(this.labelMesh);
|
||||
}
|
||||
if (position != void 0) {
|
||||
this.labelMesh.position.copy(position);
|
||||
}
|
||||
this.labelMesh.visible = visible;
|
||||
}
|
||||
/**
|
||||
* INTERNAL Creates the Blurring Plane
|
||||
* @param {number} res The square resolution of this object's lightMap.
|
||||
* @param {WebGLRenderTexture} lightMap The lightmap to initialize the plane with.
|
||||
*/
|
||||
_initializeBlurPlane(res, lightMap = null) {
|
||||
const blurMaterial = new THREE.MeshBasicMaterial();
|
||||
blurMaterial.uniforms = {
|
||||
previousShadowMap: { value: null },
|
||||
pixelOffset: { value: 1 / res },
|
||||
polygonOffset: true,
|
||||
polygonOffsetFactor: -1,
|
||||
polygonOffsetUnits: 3
|
||||
};
|
||||
blurMaterial.onBeforeCompile = (shader) => {
|
||||
shader.vertexShader = "#define USE_UV\n" + shader.vertexShader.slice(0, -1) + " gl_Position = vec4((uv - 0.5) * 2.0, 1.0, 1.0); }";
|
||||
const bodyStart = shader.fragmentShader.indexOf("void main() {");
|
||||
shader.fragmentShader = "#define USE_UV\n" + shader.fragmentShader.slice(0, bodyStart) + " uniform sampler2D previousShadowMap;\n uniform float pixelOffset;\n" + shader.fragmentShader.slice(bodyStart - 1, -1) + ` gl_FragColor.rgb = (
|
||||
texture2D(previousShadowMap, vUv + vec2( pixelOffset, 0.0 )).rgb +
|
||||
texture2D(previousShadowMap, vUv + vec2( 0.0 , pixelOffset)).rgb +
|
||||
texture2D(previousShadowMap, vUv + vec2( 0.0 , -pixelOffset)).rgb +
|
||||
texture2D(previousShadowMap, vUv + vec2(-pixelOffset, 0.0 )).rgb +
|
||||
texture2D(previousShadowMap, vUv + vec2( pixelOffset, pixelOffset)).rgb +
|
||||
texture2D(previousShadowMap, vUv + vec2(-pixelOffset, pixelOffset)).rgb +
|
||||
texture2D(previousShadowMap, vUv + vec2( pixelOffset, -pixelOffset)).rgb +
|
||||
texture2D(previousShadowMap, vUv + vec2(-pixelOffset, -pixelOffset)).rgb)/8.0;
|
||||
}`;
|
||||
shader.uniforms.previousShadowMap = { value: lightMap.texture };
|
||||
shader.uniforms.pixelOffset = { value: 0.5 / res };
|
||||
blurMaterial.uniforms = shader.uniforms;
|
||||
blurMaterial.userData.shader = shader;
|
||||
this.compiled = true;
|
||||
};
|
||||
this.blurringPlane = new THREE.Mesh(new THREE.PlaneGeometry(1, 1), blurMaterial);
|
||||
this.blurringPlane.name = "Blurring Plane";
|
||||
this.blurringPlane.frustumCulled = false;
|
||||
this.blurringPlane.renderOrder = 0;
|
||||
this.blurringPlane.material.depthWrite = false;
|
||||
this.scene.add(this.blurringPlane);
|
||||
}
|
||||
}
|
||||
exports.ProgressiveLightMap = ProgressiveLightMap;
|
||||
//# sourceMappingURL=ProgressiveLightmap.cjs.map
|
||||
1
node_modules/three-stdlib/misc/ProgressiveLightmap.cjs.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/ProgressiveLightmap.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
60
node_modules/three-stdlib/misc/ProgressiveLightmap.d.ts
generated
vendored
Normal file
60
node_modules/three-stdlib/misc/ProgressiveLightmap.d.ts
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
import {
|
||||
Camera,
|
||||
Material,
|
||||
Mesh,
|
||||
MeshBasicMaterial,
|
||||
MeshPhongMaterial,
|
||||
Object3D,
|
||||
PlaneGeometry,
|
||||
Texture,
|
||||
Vector3,
|
||||
WebGLRenderer,
|
||||
Scene,
|
||||
WebGLRenderTarget,
|
||||
} from 'three'
|
||||
|
||||
export interface UVBoxes {
|
||||
w: number
|
||||
h: number
|
||||
index: number
|
||||
}
|
||||
|
||||
export interface LightMapContainers {
|
||||
basicMat: Material | Material[]
|
||||
object: Object3D
|
||||
}
|
||||
|
||||
export class ProgressiveLightMap {
|
||||
renderer: WebGLRenderer
|
||||
res: number
|
||||
lightMapContainers: LightMapContainers[]
|
||||
compiled: boolean
|
||||
scene: Scene
|
||||
tinyTarget: WebGLRenderTarget
|
||||
buffer1Active: boolean
|
||||
firstUpdate: boolean
|
||||
warned: boolean
|
||||
|
||||
progressiveLightMap1: WebGLRenderTarget
|
||||
progressiveLightMap2: WebGLRenderTarget
|
||||
|
||||
uvMat: MeshPhongMaterial
|
||||
|
||||
uv_boxes: UVBoxes[]
|
||||
|
||||
blurringPlane: Mesh<PlaneGeometry, MeshBasicMaterial>
|
||||
|
||||
labelMaterial: MeshBasicMaterial
|
||||
labelPlane: PlaneGeometry
|
||||
labelMesh: Mesh<PlaneGeometry, MeshBasicMaterial>
|
||||
|
||||
constructor(renderer: WebGLRenderer, res?: number)
|
||||
|
||||
addObjectsToLightMap(objects: Object3D[]): void
|
||||
|
||||
update(camera: Camera, blendWindow?: number, blurEdges?: boolean): void
|
||||
|
||||
showDebugLightmap(visible: boolean, position?: Vector3): void
|
||||
|
||||
private _initializeBlurPlane(res: number, lightMap?: Texture | null): void
|
||||
}
|
||||
189
node_modules/three-stdlib/misc/ProgressiveLightmap.js
generated
vendored
Normal file
189
node_modules/three-stdlib/misc/ProgressiveLightmap.js
generated
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
import { Scene, WebGLRenderTarget, FloatType, MeshPhongMaterial, MeshBasicMaterial, DoubleSide, PlaneGeometry, Mesh } from "three";
|
||||
import potpack from "potpack";
|
||||
import { UV1 } from "../_polyfill/uv1.js";
|
||||
class ProgressiveLightMap {
|
||||
constructor(renderer, res = 1024) {
|
||||
this.renderer = renderer;
|
||||
this.res = res;
|
||||
this.lightMapContainers = [];
|
||||
this.compiled = false;
|
||||
this.scene = new Scene();
|
||||
this.scene.background = null;
|
||||
this.tinyTarget = new WebGLRenderTarget(1, 1);
|
||||
this.buffer1Active = false;
|
||||
this.firstUpdate = true;
|
||||
this.warned = false;
|
||||
const format = /(Android|iPad|iPhone|iPod)/g.test(navigator.userAgent) ? alfFloatType : FloatType;
|
||||
this.progressiveLightMap1 = new WebGLRenderTarget(this.res, this.res, { type: format });
|
||||
this.progressiveLightMap2 = new WebGLRenderTarget(this.res, this.res, { type: format });
|
||||
this.uvMat = new MeshPhongMaterial();
|
||||
this.uvMat.uniforms = {};
|
||||
this.uvMat.onBeforeCompile = (shader) => {
|
||||
shader.vertexShader = "#define USE_LIGHTMAP\n" + shader.vertexShader.slice(0, -1) + ` gl_Position = vec4((${UV1} - 0.5) * 2.0, 1.0, 1.0); }`;
|
||||
const bodyStart = shader.fragmentShader.indexOf("void main() {");
|
||||
shader.fragmentShader = `varying vec2 v${UV1 === "uv1" ? UV1 : "Uv2"};
|
||||
` + shader.fragmentShader.slice(0, bodyStart) + " uniform sampler2D previousShadowMap;\n uniform float averagingWindow;\n" + shader.fragmentShader.slice(bodyStart - 1, -1) + `
|
||||
vec3 texelOld = texture2D(previousShadowMap, v${UV1 === "uv1" ? UV1 : "Uv2"}).rgb;
|
||||
gl_FragColor.rgb = mix(texelOld, gl_FragColor.rgb, 1.0/averagingWindow);
|
||||
}`;
|
||||
shader.uniforms.previousShadowMap = { value: this.progressiveLightMap1.texture };
|
||||
shader.uniforms.averagingWindow = { value: 100 };
|
||||
this.uvMat.uniforms = shader.uniforms;
|
||||
this.uvMat.userData.shader = shader;
|
||||
this.compiled = true;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Sets these objects' materials' lightmaps and modifies their uv1's.
|
||||
* @param {Object3D} objects An array of objects and lights to set up your lightmap.
|
||||
*/
|
||||
addObjectsToLightMap(objects) {
|
||||
this.uv_boxes = [];
|
||||
const padding = 3 / this.res;
|
||||
for (let ob = 0; ob < objects.length; ob++) {
|
||||
const object = objects[ob];
|
||||
if (object.isLight) {
|
||||
this.scene.attach(object);
|
||||
continue;
|
||||
}
|
||||
if (!object.geometry.hasAttribute("uv")) {
|
||||
console.warn("All lightmap objects need UVs!");
|
||||
continue;
|
||||
}
|
||||
if (this.blurringPlane == null) {
|
||||
this._initializeBlurPlane(this.res, this.progressiveLightMap1);
|
||||
}
|
||||
object.material.lightMap = this.progressiveLightMap2.texture;
|
||||
object.material.dithering = true;
|
||||
object.castShadow = true;
|
||||
object.receiveShadow = true;
|
||||
object.renderOrder = 1e3 + ob;
|
||||
this.uv_boxes.push({ w: 1 + padding * 2, h: 1 + padding * 2, index: ob });
|
||||
this.lightMapContainers.push({ basicMat: object.material, object });
|
||||
this.compiled = false;
|
||||
}
|
||||
const dimensions = potpack(this.uv_boxes);
|
||||
this.uv_boxes.forEach((box) => {
|
||||
const uv1 = objects[box.index].geometry.getAttribute("uv").clone();
|
||||
for (let i = 0; i < uv1.array.length; i += uv1.itemSize) {
|
||||
uv1.array[i] = (uv1.array[i] + box.x + padding) / dimensions.w;
|
||||
uv1.array[i + 1] = (uv1.array[i + 1] + box.y + padding) / dimensions.h;
|
||||
}
|
||||
objects[box.index].geometry.setAttribute(UV1, uv1);
|
||||
objects[box.index].geometry.getAttribute(UV1).needsUpdate = true;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* This function renders each mesh one at a time into their respective surface maps
|
||||
* @param {Camera} camera Standard Rendering Camera
|
||||
* @param {number} blendWindow When >1, samples will accumulate over time.
|
||||
* @param {boolean} blurEdges Whether to fix UV Edges via blurring
|
||||
*/
|
||||
update(camera, blendWindow = 100, blurEdges = true) {
|
||||
if (this.blurringPlane == null) {
|
||||
return;
|
||||
}
|
||||
const oldTarget = this.renderer.getRenderTarget();
|
||||
this.blurringPlane.visible = blurEdges;
|
||||
for (let l = 0; l < this.lightMapContainers.length; l++) {
|
||||
this.lightMapContainers[l].object.oldScene = this.lightMapContainers[l].object.parent;
|
||||
this.scene.attach(this.lightMapContainers[l].object);
|
||||
}
|
||||
if (this.firstUpdate) {
|
||||
this.renderer.setRenderTarget(this.tinyTarget);
|
||||
this.renderer.render(this.scene, camera);
|
||||
this.firstUpdate = false;
|
||||
}
|
||||
for (let l = 0; l < this.lightMapContainers.length; l++) {
|
||||
this.uvMat.uniforms.averagingWindow = { value: blendWindow };
|
||||
this.lightMapContainers[l].object.material = this.uvMat;
|
||||
this.lightMapContainers[l].object.oldFrustumCulled = this.lightMapContainers[l].object.frustumCulled;
|
||||
this.lightMapContainers[l].object.frustumCulled = false;
|
||||
}
|
||||
const activeMap = this.buffer1Active ? this.progressiveLightMap1 : this.progressiveLightMap2;
|
||||
const inactiveMap = this.buffer1Active ? this.progressiveLightMap2 : this.progressiveLightMap1;
|
||||
this.renderer.setRenderTarget(activeMap);
|
||||
this.uvMat.uniforms.previousShadowMap = { value: inactiveMap.texture };
|
||||
this.blurringPlane.material.uniforms.previousShadowMap = { value: inactiveMap.texture };
|
||||
this.buffer1Active = !this.buffer1Active;
|
||||
this.renderer.render(this.scene, camera);
|
||||
for (let l = 0; l < this.lightMapContainers.length; l++) {
|
||||
this.lightMapContainers[l].object.frustumCulled = this.lightMapContainers[l].object.oldFrustumCulled;
|
||||
this.lightMapContainers[l].object.material = this.lightMapContainers[l].basicMat;
|
||||
this.lightMapContainers[l].object.oldScene.attach(this.lightMapContainers[l].object);
|
||||
}
|
||||
this.renderer.setRenderTarget(oldTarget);
|
||||
}
|
||||
/** DEBUG
|
||||
* Draw the lightmap in the main scene. Call this after adding the objects to it.
|
||||
* @param {boolean} visible Whether the debug plane should be visible
|
||||
* @param {Vector3} position Where the debug plane should be drawn
|
||||
*/
|
||||
showDebugLightmap(visible, position = void 0) {
|
||||
if (this.lightMapContainers.length == 0) {
|
||||
if (!this.warned) {
|
||||
console.warn("Call this after adding the objects!");
|
||||
this.warned = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (this.labelMesh == null) {
|
||||
this.labelMaterial = new MeshBasicMaterial({
|
||||
map: this.progressiveLightMap1.texture,
|
||||
side: DoubleSide
|
||||
});
|
||||
this.labelPlane = new PlaneGeometry(100, 100);
|
||||
this.labelMesh = new Mesh(this.labelPlane, this.labelMaterial);
|
||||
this.labelMesh.position.y = 250;
|
||||
this.lightMapContainers[0].object.parent.add(this.labelMesh);
|
||||
}
|
||||
if (position != void 0) {
|
||||
this.labelMesh.position.copy(position);
|
||||
}
|
||||
this.labelMesh.visible = visible;
|
||||
}
|
||||
/**
|
||||
* INTERNAL Creates the Blurring Plane
|
||||
* @param {number} res The square resolution of this object's lightMap.
|
||||
* @param {WebGLRenderTexture} lightMap The lightmap to initialize the plane with.
|
||||
*/
|
||||
_initializeBlurPlane(res, lightMap = null) {
|
||||
const blurMaterial = new MeshBasicMaterial();
|
||||
blurMaterial.uniforms = {
|
||||
previousShadowMap: { value: null },
|
||||
pixelOffset: { value: 1 / res },
|
||||
polygonOffset: true,
|
||||
polygonOffsetFactor: -1,
|
||||
polygonOffsetUnits: 3
|
||||
};
|
||||
blurMaterial.onBeforeCompile = (shader) => {
|
||||
shader.vertexShader = "#define USE_UV\n" + shader.vertexShader.slice(0, -1) + " gl_Position = vec4((uv - 0.5) * 2.0, 1.0, 1.0); }";
|
||||
const bodyStart = shader.fragmentShader.indexOf("void main() {");
|
||||
shader.fragmentShader = "#define USE_UV\n" + shader.fragmentShader.slice(0, bodyStart) + " uniform sampler2D previousShadowMap;\n uniform float pixelOffset;\n" + shader.fragmentShader.slice(bodyStart - 1, -1) + ` gl_FragColor.rgb = (
|
||||
texture2D(previousShadowMap, vUv + vec2( pixelOffset, 0.0 )).rgb +
|
||||
texture2D(previousShadowMap, vUv + vec2( 0.0 , pixelOffset)).rgb +
|
||||
texture2D(previousShadowMap, vUv + vec2( 0.0 , -pixelOffset)).rgb +
|
||||
texture2D(previousShadowMap, vUv + vec2(-pixelOffset, 0.0 )).rgb +
|
||||
texture2D(previousShadowMap, vUv + vec2( pixelOffset, pixelOffset)).rgb +
|
||||
texture2D(previousShadowMap, vUv + vec2(-pixelOffset, pixelOffset)).rgb +
|
||||
texture2D(previousShadowMap, vUv + vec2( pixelOffset, -pixelOffset)).rgb +
|
||||
texture2D(previousShadowMap, vUv + vec2(-pixelOffset, -pixelOffset)).rgb)/8.0;
|
||||
}`;
|
||||
shader.uniforms.previousShadowMap = { value: lightMap.texture };
|
||||
shader.uniforms.pixelOffset = { value: 0.5 / res };
|
||||
blurMaterial.uniforms = shader.uniforms;
|
||||
blurMaterial.userData.shader = shader;
|
||||
this.compiled = true;
|
||||
};
|
||||
this.blurringPlane = new Mesh(new PlaneGeometry(1, 1), blurMaterial);
|
||||
this.blurringPlane.name = "Blurring Plane";
|
||||
this.blurringPlane.frustumCulled = false;
|
||||
this.blurringPlane.renderOrder = 0;
|
||||
this.blurringPlane.material.depthWrite = false;
|
||||
this.scene.add(this.blurringPlane);
|
||||
}
|
||||
}
|
||||
export {
|
||||
ProgressiveLightMap
|
||||
};
|
||||
//# sourceMappingURL=ProgressiveLightmap.js.map
|
||||
1
node_modules/three-stdlib/misc/ProgressiveLightmap.js.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/ProgressiveLightmap.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
354
node_modules/three-stdlib/misc/RollerCoaster.cjs
generated
vendored
Normal file
354
node_modules/three-stdlib/misc/RollerCoaster.cjs
generated
vendored
Normal file
@@ -0,0 +1,354 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
||||
const THREE = require("three");
|
||||
class RollerCoasterGeometry extends THREE.BufferGeometry {
|
||||
constructor(curve, divisions) {
|
||||
super();
|
||||
const vertices = [];
|
||||
const normals = [];
|
||||
const colors = [];
|
||||
const color1 = [1, 1, 1];
|
||||
const color2 = [1, 1, 0];
|
||||
const up = new THREE.Vector3(0, 1, 0);
|
||||
const forward = new THREE.Vector3();
|
||||
const right = new THREE.Vector3();
|
||||
const quaternion = new THREE.Quaternion();
|
||||
const prevQuaternion = new THREE.Quaternion();
|
||||
prevQuaternion.setFromAxisAngle(up, Math.PI / 2);
|
||||
const point = new THREE.Vector3();
|
||||
const prevPoint = new THREE.Vector3();
|
||||
prevPoint.copy(curve.getPointAt(0));
|
||||
const step = [
|
||||
new THREE.Vector3(-0.225, 0, 0),
|
||||
new THREE.Vector3(0, -0.05, 0),
|
||||
new THREE.Vector3(0, -0.175, 0),
|
||||
new THREE.Vector3(0, -0.05, 0),
|
||||
new THREE.Vector3(0.225, 0, 0),
|
||||
new THREE.Vector3(0, -0.175, 0)
|
||||
];
|
||||
const PI2 = Math.PI * 2;
|
||||
let sides = 5;
|
||||
const tube1 = [];
|
||||
for (let i = 0; i < sides; i++) {
|
||||
const angle = i / sides * PI2;
|
||||
tube1.push(new THREE.Vector3(Math.sin(angle) * 0.06, Math.cos(angle) * 0.06, 0));
|
||||
}
|
||||
sides = 6;
|
||||
const tube2 = [];
|
||||
for (let i = 0; i < sides; i++) {
|
||||
const angle = i / sides * PI2;
|
||||
tube2.push(new THREE.Vector3(Math.sin(angle) * 0.025, Math.cos(angle) * 0.025, 0));
|
||||
}
|
||||
const vector = new THREE.Vector3();
|
||||
const normal = new THREE.Vector3();
|
||||
function drawShape(shape, color) {
|
||||
normal.set(0, 0, -1).applyQuaternion(quaternion);
|
||||
for (let j = 0; j < shape.length; j++) {
|
||||
vector.copy(shape[j]);
|
||||
vector.applyQuaternion(quaternion);
|
||||
vector.add(point);
|
||||
vertices.push(vector.x, vector.y, vector.z);
|
||||
normals.push(normal.x, normal.y, normal.z);
|
||||
colors.push(color[0], color[1], color[2]);
|
||||
}
|
||||
normal.set(0, 0, 1).applyQuaternion(quaternion);
|
||||
for (let j = shape.length - 1; j >= 0; j--) {
|
||||
vector.copy(shape[j]);
|
||||
vector.applyQuaternion(quaternion);
|
||||
vector.add(point);
|
||||
vertices.push(vector.x, vector.y, vector.z);
|
||||
normals.push(normal.x, normal.y, normal.z);
|
||||
colors.push(color[0], color[1], color[2]);
|
||||
}
|
||||
}
|
||||
const vector1 = new THREE.Vector3();
|
||||
const vector2 = new THREE.Vector3();
|
||||
const vector3 = new THREE.Vector3();
|
||||
const vector4 = new THREE.Vector3();
|
||||
const normal1 = new THREE.Vector3();
|
||||
const normal2 = new THREE.Vector3();
|
||||
const normal3 = new THREE.Vector3();
|
||||
const normal4 = new THREE.Vector3();
|
||||
function extrudeShape(shape, offset2, color) {
|
||||
for (let j = 0, jl = shape.length; j < jl; j++) {
|
||||
const point1 = shape[j];
|
||||
const point2 = shape[(j + 1) % jl];
|
||||
vector1.copy(point1).add(offset2);
|
||||
vector1.applyQuaternion(quaternion);
|
||||
vector1.add(point);
|
||||
vector2.copy(point2).add(offset2);
|
||||
vector2.applyQuaternion(quaternion);
|
||||
vector2.add(point);
|
||||
vector3.copy(point2).add(offset2);
|
||||
vector3.applyQuaternion(prevQuaternion);
|
||||
vector3.add(prevPoint);
|
||||
vector4.copy(point1).add(offset2);
|
||||
vector4.applyQuaternion(prevQuaternion);
|
||||
vector4.add(prevPoint);
|
||||
vertices.push(vector1.x, vector1.y, vector1.z);
|
||||
vertices.push(vector2.x, vector2.y, vector2.z);
|
||||
vertices.push(vector4.x, vector4.y, vector4.z);
|
||||
vertices.push(vector2.x, vector2.y, vector2.z);
|
||||
vertices.push(vector3.x, vector3.y, vector3.z);
|
||||
vertices.push(vector4.x, vector4.y, vector4.z);
|
||||
normal1.copy(point1);
|
||||
normal1.applyQuaternion(quaternion);
|
||||
normal1.normalize();
|
||||
normal2.copy(point2);
|
||||
normal2.applyQuaternion(quaternion);
|
||||
normal2.normalize();
|
||||
normal3.copy(point2);
|
||||
normal3.applyQuaternion(prevQuaternion);
|
||||
normal3.normalize();
|
||||
normal4.copy(point1);
|
||||
normal4.applyQuaternion(prevQuaternion);
|
||||
normal4.normalize();
|
||||
normals.push(normal1.x, normal1.y, normal1.z);
|
||||
normals.push(normal2.x, normal2.y, normal2.z);
|
||||
normals.push(normal4.x, normal4.y, normal4.z);
|
||||
normals.push(normal2.x, normal2.y, normal2.z);
|
||||
normals.push(normal3.x, normal3.y, normal3.z);
|
||||
normals.push(normal4.x, normal4.y, normal4.z);
|
||||
colors.push(color[0], color[1], color[2]);
|
||||
colors.push(color[0], color[1], color[2]);
|
||||
colors.push(color[0], color[1], color[2]);
|
||||
colors.push(color[0], color[1], color[2]);
|
||||
colors.push(color[0], color[1], color[2]);
|
||||
colors.push(color[0], color[1], color[2]);
|
||||
}
|
||||
}
|
||||
const offset = new THREE.Vector3();
|
||||
for (let i = 1; i <= divisions; i++) {
|
||||
point.copy(curve.getPointAt(i / divisions));
|
||||
up.set(0, 1, 0);
|
||||
forward.subVectors(point, prevPoint).normalize();
|
||||
right.crossVectors(up, forward).normalize();
|
||||
up.crossVectors(forward, right);
|
||||
const angle = Math.atan2(forward.x, forward.z);
|
||||
quaternion.setFromAxisAngle(up, angle);
|
||||
if (i % 2 === 0) {
|
||||
drawShape(step, color2);
|
||||
}
|
||||
extrudeShape(tube1, offset.set(0, -0.125, 0), color2);
|
||||
extrudeShape(tube2, offset.set(0.2, 0, 0), color1);
|
||||
extrudeShape(tube2, offset.set(-0.2, 0, 0), color1);
|
||||
prevPoint.copy(point);
|
||||
prevQuaternion.copy(quaternion);
|
||||
}
|
||||
this.setAttribute("position", new THREE.BufferAttribute(new Float32Array(vertices), 3));
|
||||
this.setAttribute("normal", new THREE.BufferAttribute(new Float32Array(normals), 3));
|
||||
this.setAttribute("color", new THREE.BufferAttribute(new Float32Array(colors), 3));
|
||||
}
|
||||
}
|
||||
class RollerCoasterLiftersGeometry extends THREE.BufferGeometry {
|
||||
constructor(curve, divisions) {
|
||||
super();
|
||||
const vertices = [];
|
||||
const normals = [];
|
||||
const quaternion = new THREE.Quaternion();
|
||||
const up = new THREE.Vector3(0, 1, 0);
|
||||
const point = new THREE.Vector3();
|
||||
const tangent = new THREE.Vector3();
|
||||
const tube1 = [new THREE.Vector3(0, 0.05, -0.05), new THREE.Vector3(0, 0.05, 0.05), new THREE.Vector3(0, -0.05, 0)];
|
||||
const tube2 = [new THREE.Vector3(-0.05, 0, 0.05), new THREE.Vector3(-0.05, 0, -0.05), new THREE.Vector3(0.05, 0, 0)];
|
||||
const tube3 = [new THREE.Vector3(0.05, 0, -0.05), new THREE.Vector3(0.05, 0, 0.05), new THREE.Vector3(-0.05, 0, 0)];
|
||||
const vector1 = new THREE.Vector3();
|
||||
const vector2 = new THREE.Vector3();
|
||||
const vector3 = new THREE.Vector3();
|
||||
const vector4 = new THREE.Vector3();
|
||||
const normal1 = new THREE.Vector3();
|
||||
const normal2 = new THREE.Vector3();
|
||||
const normal3 = new THREE.Vector3();
|
||||
const normal4 = new THREE.Vector3();
|
||||
function extrudeShape(shape, fromPoint2, toPoint2) {
|
||||
for (let j = 0, jl = shape.length; j < jl; j++) {
|
||||
const point1 = shape[j];
|
||||
const point2 = shape[(j + 1) % jl];
|
||||
vector1.copy(point1);
|
||||
vector1.applyQuaternion(quaternion);
|
||||
vector1.add(fromPoint2);
|
||||
vector2.copy(point2);
|
||||
vector2.applyQuaternion(quaternion);
|
||||
vector2.add(fromPoint2);
|
||||
vector3.copy(point2);
|
||||
vector3.applyQuaternion(quaternion);
|
||||
vector3.add(toPoint2);
|
||||
vector4.copy(point1);
|
||||
vector4.applyQuaternion(quaternion);
|
||||
vector4.add(toPoint2);
|
||||
vertices.push(vector1.x, vector1.y, vector1.z);
|
||||
vertices.push(vector2.x, vector2.y, vector2.z);
|
||||
vertices.push(vector4.x, vector4.y, vector4.z);
|
||||
vertices.push(vector2.x, vector2.y, vector2.z);
|
||||
vertices.push(vector3.x, vector3.y, vector3.z);
|
||||
vertices.push(vector4.x, vector4.y, vector4.z);
|
||||
normal1.copy(point1);
|
||||
normal1.applyQuaternion(quaternion);
|
||||
normal1.normalize();
|
||||
normal2.copy(point2);
|
||||
normal2.applyQuaternion(quaternion);
|
||||
normal2.normalize();
|
||||
normal3.copy(point2);
|
||||
normal3.applyQuaternion(quaternion);
|
||||
normal3.normalize();
|
||||
normal4.copy(point1);
|
||||
normal4.applyQuaternion(quaternion);
|
||||
normal4.normalize();
|
||||
normals.push(normal1.x, normal1.y, normal1.z);
|
||||
normals.push(normal2.x, normal2.y, normal2.z);
|
||||
normals.push(normal4.x, normal4.y, normal4.z);
|
||||
normals.push(normal2.x, normal2.y, normal2.z);
|
||||
normals.push(normal3.x, normal3.y, normal3.z);
|
||||
normals.push(normal4.x, normal4.y, normal4.z);
|
||||
}
|
||||
}
|
||||
const fromPoint = new THREE.Vector3();
|
||||
const toPoint = new THREE.Vector3();
|
||||
for (let i = 1; i <= divisions; i++) {
|
||||
point.copy(curve.getPointAt(i / divisions));
|
||||
tangent.copy(curve.getTangentAt(i / divisions));
|
||||
const angle = Math.atan2(tangent.x, tangent.z);
|
||||
quaternion.setFromAxisAngle(up, angle);
|
||||
if (point.y > 10) {
|
||||
fromPoint.set(-0.75, -0.35, 0);
|
||||
fromPoint.applyQuaternion(quaternion);
|
||||
fromPoint.add(point);
|
||||
toPoint.set(0.75, -0.35, 0);
|
||||
toPoint.applyQuaternion(quaternion);
|
||||
toPoint.add(point);
|
||||
extrudeShape(tube1, fromPoint, toPoint);
|
||||
fromPoint.set(-0.7, -0.3, 0);
|
||||
fromPoint.applyQuaternion(quaternion);
|
||||
fromPoint.add(point);
|
||||
toPoint.set(-0.7, -point.y, 0);
|
||||
toPoint.applyQuaternion(quaternion);
|
||||
toPoint.add(point);
|
||||
extrudeShape(tube2, fromPoint, toPoint);
|
||||
fromPoint.set(0.7, -0.3, 0);
|
||||
fromPoint.applyQuaternion(quaternion);
|
||||
fromPoint.add(point);
|
||||
toPoint.set(0.7, -point.y, 0);
|
||||
toPoint.applyQuaternion(quaternion);
|
||||
toPoint.add(point);
|
||||
extrudeShape(tube3, fromPoint, toPoint);
|
||||
} else {
|
||||
fromPoint.set(0, -0.2, 0);
|
||||
fromPoint.applyQuaternion(quaternion);
|
||||
fromPoint.add(point);
|
||||
toPoint.set(0, -point.y, 0);
|
||||
toPoint.applyQuaternion(quaternion);
|
||||
toPoint.add(point);
|
||||
extrudeShape(tube3, fromPoint, toPoint);
|
||||
}
|
||||
}
|
||||
this.setAttribute("position", new THREE.BufferAttribute(new Float32Array(vertices), 3));
|
||||
this.setAttribute("normal", new THREE.BufferAttribute(new Float32Array(normals), 3));
|
||||
}
|
||||
}
|
||||
class RollerCoasterShadowGeometry extends THREE.BufferGeometry {
|
||||
constructor(curve, divisions) {
|
||||
super();
|
||||
const vertices = [];
|
||||
const up = new THREE.Vector3(0, 1, 0);
|
||||
const forward = new THREE.Vector3();
|
||||
const quaternion = new THREE.Quaternion();
|
||||
const prevQuaternion = new THREE.Quaternion();
|
||||
prevQuaternion.setFromAxisAngle(up, Math.PI / 2);
|
||||
const point = new THREE.Vector3();
|
||||
const prevPoint = new THREE.Vector3();
|
||||
prevPoint.copy(curve.getPointAt(0));
|
||||
prevPoint.y = 0;
|
||||
const vector1 = new THREE.Vector3();
|
||||
const vector2 = new THREE.Vector3();
|
||||
const vector3 = new THREE.Vector3();
|
||||
const vector4 = new THREE.Vector3();
|
||||
for (let i = 1; i <= divisions; i++) {
|
||||
point.copy(curve.getPointAt(i / divisions));
|
||||
point.y = 0;
|
||||
forward.subVectors(point, prevPoint);
|
||||
const angle = Math.atan2(forward.x, forward.z);
|
||||
quaternion.setFromAxisAngle(up, angle);
|
||||
vector1.set(-0.3, 0, 0);
|
||||
vector1.applyQuaternion(quaternion);
|
||||
vector1.add(point);
|
||||
vector2.set(0.3, 0, 0);
|
||||
vector2.applyQuaternion(quaternion);
|
||||
vector2.add(point);
|
||||
vector3.set(0.3, 0, 0);
|
||||
vector3.applyQuaternion(prevQuaternion);
|
||||
vector3.add(prevPoint);
|
||||
vector4.set(-0.3, 0, 0);
|
||||
vector4.applyQuaternion(prevQuaternion);
|
||||
vector4.add(prevPoint);
|
||||
vertices.push(vector1.x, vector1.y, vector1.z);
|
||||
vertices.push(vector2.x, vector2.y, vector2.z);
|
||||
vertices.push(vector4.x, vector4.y, vector4.z);
|
||||
vertices.push(vector2.x, vector2.y, vector2.z);
|
||||
vertices.push(vector3.x, vector3.y, vector3.z);
|
||||
vertices.push(vector4.x, vector4.y, vector4.z);
|
||||
prevPoint.copy(point);
|
||||
prevQuaternion.copy(quaternion);
|
||||
}
|
||||
this.setAttribute("position", new THREE.BufferAttribute(new Float32Array(vertices), 3));
|
||||
}
|
||||
}
|
||||
class SkyGeometry extends THREE.BufferGeometry {
|
||||
constructor() {
|
||||
super();
|
||||
const vertices = [];
|
||||
for (let i = 0; i < 100; i++) {
|
||||
const x = Math.random() * 800 - 400;
|
||||
const y = Math.random() * 50 + 50;
|
||||
const z = Math.random() * 800 - 400;
|
||||
const size = Math.random() * 40 + 20;
|
||||
vertices.push(x - size, y, z - size);
|
||||
vertices.push(x + size, y, z - size);
|
||||
vertices.push(x - size, y, z + size);
|
||||
vertices.push(x + size, y, z - size);
|
||||
vertices.push(x + size, y, z + size);
|
||||
vertices.push(x - size, y, z + size);
|
||||
}
|
||||
this.setAttribute("position", new THREE.BufferAttribute(new Float32Array(vertices), 3));
|
||||
}
|
||||
}
|
||||
class TreesGeometry extends THREE.BufferGeometry {
|
||||
constructor(landscape) {
|
||||
super();
|
||||
const vertices = [];
|
||||
const colors = [];
|
||||
const raycaster = new THREE.Raycaster();
|
||||
raycaster.ray.direction.set(0, -1, 0);
|
||||
const _color = new THREE.Color();
|
||||
for (let i = 0; i < 2e3; i++) {
|
||||
const x = Math.random() * 500 - 250;
|
||||
const z = Math.random() * 500 - 250;
|
||||
raycaster.ray.origin.set(x, 50, z);
|
||||
const intersections = raycaster.intersectObject(landscape);
|
||||
if (intersections.length === 0)
|
||||
continue;
|
||||
const y = intersections[0].point.y;
|
||||
const height = Math.random() * 5 + 0.5;
|
||||
let angle = Math.random() * Math.PI * 2;
|
||||
vertices.push(x + Math.sin(angle), y, z + Math.cos(angle));
|
||||
vertices.push(x, y + height, z);
|
||||
vertices.push(x + Math.sin(angle + Math.PI), y, z + Math.cos(angle + Math.PI));
|
||||
angle += Math.PI / 2;
|
||||
vertices.push(x + Math.sin(angle), y, z + Math.cos(angle));
|
||||
vertices.push(x, y + height, z);
|
||||
vertices.push(x + Math.sin(angle + Math.PI), y, z + Math.cos(angle + Math.PI));
|
||||
const random = Math.random() * 0.1;
|
||||
for (let j = 0; j < 6; j++) {
|
||||
_color.setRGB(0.2 + random, 0.4 + random, 0, "srgb");
|
||||
colors.push(_color.r, _color.g, _color.b);
|
||||
}
|
||||
}
|
||||
this.setAttribute("position", new THREE.BufferAttribute(new Float32Array(vertices), 3));
|
||||
this.setAttribute("color", new THREE.BufferAttribute(new Float32Array(colors), 3));
|
||||
}
|
||||
}
|
||||
exports.RollerCoasterGeometry = RollerCoasterGeometry;
|
||||
exports.RollerCoasterLiftersGeometry = RollerCoasterLiftersGeometry;
|
||||
exports.RollerCoasterShadowGeometry = RollerCoasterShadowGeometry;
|
||||
exports.SkyGeometry = SkyGeometry;
|
||||
exports.TreesGeometry = TreesGeometry;
|
||||
//# sourceMappingURL=RollerCoaster.cjs.map
|
||||
1
node_modules/three-stdlib/misc/RollerCoaster.cjs.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/RollerCoaster.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
21
node_modules/three-stdlib/misc/RollerCoaster.d.ts
generated
vendored
Normal file
21
node_modules/three-stdlib/misc/RollerCoaster.d.ts
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import { BufferGeometry, Curve, Mesh, Vector3 } from 'three'
|
||||
|
||||
export class RollerCoasterGeometry extends BufferGeometry {
|
||||
constructor(curve: Curve<Vector3>, divisions: number)
|
||||
}
|
||||
|
||||
export class RollerCoasterLiftersGeometry extends BufferGeometry {
|
||||
constructor(curve: Curve<Vector3>, divisions: number)
|
||||
}
|
||||
|
||||
export class RollerCoasterShadowGeometry extends BufferGeometry {
|
||||
constructor(curve: Curve<Vector3>, divisions: number)
|
||||
}
|
||||
|
||||
export class SkyGeometry extends BufferGeometry {
|
||||
constructor(curve: Curve<Vector3>, divisions: number)
|
||||
}
|
||||
|
||||
export class TreesGeometry extends BufferGeometry {
|
||||
constructor(landscape: Mesh)
|
||||
}
|
||||
354
node_modules/three-stdlib/misc/RollerCoaster.js
generated
vendored
Normal file
354
node_modules/three-stdlib/misc/RollerCoaster.js
generated
vendored
Normal file
@@ -0,0 +1,354 @@
|
||||
import { BufferGeometry, Vector3, Quaternion, BufferAttribute, Raycaster, Color } from "three";
|
||||
class RollerCoasterGeometry extends BufferGeometry {
|
||||
constructor(curve, divisions) {
|
||||
super();
|
||||
const vertices = [];
|
||||
const normals = [];
|
||||
const colors = [];
|
||||
const color1 = [1, 1, 1];
|
||||
const color2 = [1, 1, 0];
|
||||
const up = new Vector3(0, 1, 0);
|
||||
const forward = new Vector3();
|
||||
const right = new Vector3();
|
||||
const quaternion = new Quaternion();
|
||||
const prevQuaternion = new Quaternion();
|
||||
prevQuaternion.setFromAxisAngle(up, Math.PI / 2);
|
||||
const point = new Vector3();
|
||||
const prevPoint = new Vector3();
|
||||
prevPoint.copy(curve.getPointAt(0));
|
||||
const step = [
|
||||
new Vector3(-0.225, 0, 0),
|
||||
new Vector3(0, -0.05, 0),
|
||||
new Vector3(0, -0.175, 0),
|
||||
new Vector3(0, -0.05, 0),
|
||||
new Vector3(0.225, 0, 0),
|
||||
new Vector3(0, -0.175, 0)
|
||||
];
|
||||
const PI2 = Math.PI * 2;
|
||||
let sides = 5;
|
||||
const tube1 = [];
|
||||
for (let i = 0; i < sides; i++) {
|
||||
const angle = i / sides * PI2;
|
||||
tube1.push(new Vector3(Math.sin(angle) * 0.06, Math.cos(angle) * 0.06, 0));
|
||||
}
|
||||
sides = 6;
|
||||
const tube2 = [];
|
||||
for (let i = 0; i < sides; i++) {
|
||||
const angle = i / sides * PI2;
|
||||
tube2.push(new Vector3(Math.sin(angle) * 0.025, Math.cos(angle) * 0.025, 0));
|
||||
}
|
||||
const vector = new Vector3();
|
||||
const normal = new Vector3();
|
||||
function drawShape(shape, color) {
|
||||
normal.set(0, 0, -1).applyQuaternion(quaternion);
|
||||
for (let j = 0; j < shape.length; j++) {
|
||||
vector.copy(shape[j]);
|
||||
vector.applyQuaternion(quaternion);
|
||||
vector.add(point);
|
||||
vertices.push(vector.x, vector.y, vector.z);
|
||||
normals.push(normal.x, normal.y, normal.z);
|
||||
colors.push(color[0], color[1], color[2]);
|
||||
}
|
||||
normal.set(0, 0, 1).applyQuaternion(quaternion);
|
||||
for (let j = shape.length - 1; j >= 0; j--) {
|
||||
vector.copy(shape[j]);
|
||||
vector.applyQuaternion(quaternion);
|
||||
vector.add(point);
|
||||
vertices.push(vector.x, vector.y, vector.z);
|
||||
normals.push(normal.x, normal.y, normal.z);
|
||||
colors.push(color[0], color[1], color[2]);
|
||||
}
|
||||
}
|
||||
const vector1 = new Vector3();
|
||||
const vector2 = new Vector3();
|
||||
const vector3 = new Vector3();
|
||||
const vector4 = new Vector3();
|
||||
const normal1 = new Vector3();
|
||||
const normal2 = new Vector3();
|
||||
const normal3 = new Vector3();
|
||||
const normal4 = new Vector3();
|
||||
function extrudeShape(shape, offset2, color) {
|
||||
for (let j = 0, jl = shape.length; j < jl; j++) {
|
||||
const point1 = shape[j];
|
||||
const point2 = shape[(j + 1) % jl];
|
||||
vector1.copy(point1).add(offset2);
|
||||
vector1.applyQuaternion(quaternion);
|
||||
vector1.add(point);
|
||||
vector2.copy(point2).add(offset2);
|
||||
vector2.applyQuaternion(quaternion);
|
||||
vector2.add(point);
|
||||
vector3.copy(point2).add(offset2);
|
||||
vector3.applyQuaternion(prevQuaternion);
|
||||
vector3.add(prevPoint);
|
||||
vector4.copy(point1).add(offset2);
|
||||
vector4.applyQuaternion(prevQuaternion);
|
||||
vector4.add(prevPoint);
|
||||
vertices.push(vector1.x, vector1.y, vector1.z);
|
||||
vertices.push(vector2.x, vector2.y, vector2.z);
|
||||
vertices.push(vector4.x, vector4.y, vector4.z);
|
||||
vertices.push(vector2.x, vector2.y, vector2.z);
|
||||
vertices.push(vector3.x, vector3.y, vector3.z);
|
||||
vertices.push(vector4.x, vector4.y, vector4.z);
|
||||
normal1.copy(point1);
|
||||
normal1.applyQuaternion(quaternion);
|
||||
normal1.normalize();
|
||||
normal2.copy(point2);
|
||||
normal2.applyQuaternion(quaternion);
|
||||
normal2.normalize();
|
||||
normal3.copy(point2);
|
||||
normal3.applyQuaternion(prevQuaternion);
|
||||
normal3.normalize();
|
||||
normal4.copy(point1);
|
||||
normal4.applyQuaternion(prevQuaternion);
|
||||
normal4.normalize();
|
||||
normals.push(normal1.x, normal1.y, normal1.z);
|
||||
normals.push(normal2.x, normal2.y, normal2.z);
|
||||
normals.push(normal4.x, normal4.y, normal4.z);
|
||||
normals.push(normal2.x, normal2.y, normal2.z);
|
||||
normals.push(normal3.x, normal3.y, normal3.z);
|
||||
normals.push(normal4.x, normal4.y, normal4.z);
|
||||
colors.push(color[0], color[1], color[2]);
|
||||
colors.push(color[0], color[1], color[2]);
|
||||
colors.push(color[0], color[1], color[2]);
|
||||
colors.push(color[0], color[1], color[2]);
|
||||
colors.push(color[0], color[1], color[2]);
|
||||
colors.push(color[0], color[1], color[2]);
|
||||
}
|
||||
}
|
||||
const offset = new Vector3();
|
||||
for (let i = 1; i <= divisions; i++) {
|
||||
point.copy(curve.getPointAt(i / divisions));
|
||||
up.set(0, 1, 0);
|
||||
forward.subVectors(point, prevPoint).normalize();
|
||||
right.crossVectors(up, forward).normalize();
|
||||
up.crossVectors(forward, right);
|
||||
const angle = Math.atan2(forward.x, forward.z);
|
||||
quaternion.setFromAxisAngle(up, angle);
|
||||
if (i % 2 === 0) {
|
||||
drawShape(step, color2);
|
||||
}
|
||||
extrudeShape(tube1, offset.set(0, -0.125, 0), color2);
|
||||
extrudeShape(tube2, offset.set(0.2, 0, 0), color1);
|
||||
extrudeShape(tube2, offset.set(-0.2, 0, 0), color1);
|
||||
prevPoint.copy(point);
|
||||
prevQuaternion.copy(quaternion);
|
||||
}
|
||||
this.setAttribute("position", new BufferAttribute(new Float32Array(vertices), 3));
|
||||
this.setAttribute("normal", new BufferAttribute(new Float32Array(normals), 3));
|
||||
this.setAttribute("color", new BufferAttribute(new Float32Array(colors), 3));
|
||||
}
|
||||
}
|
||||
class RollerCoasterLiftersGeometry extends BufferGeometry {
|
||||
constructor(curve, divisions) {
|
||||
super();
|
||||
const vertices = [];
|
||||
const normals = [];
|
||||
const quaternion = new Quaternion();
|
||||
const up = new Vector3(0, 1, 0);
|
||||
const point = new Vector3();
|
||||
const tangent = new Vector3();
|
||||
const tube1 = [new Vector3(0, 0.05, -0.05), new Vector3(0, 0.05, 0.05), new Vector3(0, -0.05, 0)];
|
||||
const tube2 = [new Vector3(-0.05, 0, 0.05), new Vector3(-0.05, 0, -0.05), new Vector3(0.05, 0, 0)];
|
||||
const tube3 = [new Vector3(0.05, 0, -0.05), new Vector3(0.05, 0, 0.05), new Vector3(-0.05, 0, 0)];
|
||||
const vector1 = new Vector3();
|
||||
const vector2 = new Vector3();
|
||||
const vector3 = new Vector3();
|
||||
const vector4 = new Vector3();
|
||||
const normal1 = new Vector3();
|
||||
const normal2 = new Vector3();
|
||||
const normal3 = new Vector3();
|
||||
const normal4 = new Vector3();
|
||||
function extrudeShape(shape, fromPoint2, toPoint2) {
|
||||
for (let j = 0, jl = shape.length; j < jl; j++) {
|
||||
const point1 = shape[j];
|
||||
const point2 = shape[(j + 1) % jl];
|
||||
vector1.copy(point1);
|
||||
vector1.applyQuaternion(quaternion);
|
||||
vector1.add(fromPoint2);
|
||||
vector2.copy(point2);
|
||||
vector2.applyQuaternion(quaternion);
|
||||
vector2.add(fromPoint2);
|
||||
vector3.copy(point2);
|
||||
vector3.applyQuaternion(quaternion);
|
||||
vector3.add(toPoint2);
|
||||
vector4.copy(point1);
|
||||
vector4.applyQuaternion(quaternion);
|
||||
vector4.add(toPoint2);
|
||||
vertices.push(vector1.x, vector1.y, vector1.z);
|
||||
vertices.push(vector2.x, vector2.y, vector2.z);
|
||||
vertices.push(vector4.x, vector4.y, vector4.z);
|
||||
vertices.push(vector2.x, vector2.y, vector2.z);
|
||||
vertices.push(vector3.x, vector3.y, vector3.z);
|
||||
vertices.push(vector4.x, vector4.y, vector4.z);
|
||||
normal1.copy(point1);
|
||||
normal1.applyQuaternion(quaternion);
|
||||
normal1.normalize();
|
||||
normal2.copy(point2);
|
||||
normal2.applyQuaternion(quaternion);
|
||||
normal2.normalize();
|
||||
normal3.copy(point2);
|
||||
normal3.applyQuaternion(quaternion);
|
||||
normal3.normalize();
|
||||
normal4.copy(point1);
|
||||
normal4.applyQuaternion(quaternion);
|
||||
normal4.normalize();
|
||||
normals.push(normal1.x, normal1.y, normal1.z);
|
||||
normals.push(normal2.x, normal2.y, normal2.z);
|
||||
normals.push(normal4.x, normal4.y, normal4.z);
|
||||
normals.push(normal2.x, normal2.y, normal2.z);
|
||||
normals.push(normal3.x, normal3.y, normal3.z);
|
||||
normals.push(normal4.x, normal4.y, normal4.z);
|
||||
}
|
||||
}
|
||||
const fromPoint = new Vector3();
|
||||
const toPoint = new Vector3();
|
||||
for (let i = 1; i <= divisions; i++) {
|
||||
point.copy(curve.getPointAt(i / divisions));
|
||||
tangent.copy(curve.getTangentAt(i / divisions));
|
||||
const angle = Math.atan2(tangent.x, tangent.z);
|
||||
quaternion.setFromAxisAngle(up, angle);
|
||||
if (point.y > 10) {
|
||||
fromPoint.set(-0.75, -0.35, 0);
|
||||
fromPoint.applyQuaternion(quaternion);
|
||||
fromPoint.add(point);
|
||||
toPoint.set(0.75, -0.35, 0);
|
||||
toPoint.applyQuaternion(quaternion);
|
||||
toPoint.add(point);
|
||||
extrudeShape(tube1, fromPoint, toPoint);
|
||||
fromPoint.set(-0.7, -0.3, 0);
|
||||
fromPoint.applyQuaternion(quaternion);
|
||||
fromPoint.add(point);
|
||||
toPoint.set(-0.7, -point.y, 0);
|
||||
toPoint.applyQuaternion(quaternion);
|
||||
toPoint.add(point);
|
||||
extrudeShape(tube2, fromPoint, toPoint);
|
||||
fromPoint.set(0.7, -0.3, 0);
|
||||
fromPoint.applyQuaternion(quaternion);
|
||||
fromPoint.add(point);
|
||||
toPoint.set(0.7, -point.y, 0);
|
||||
toPoint.applyQuaternion(quaternion);
|
||||
toPoint.add(point);
|
||||
extrudeShape(tube3, fromPoint, toPoint);
|
||||
} else {
|
||||
fromPoint.set(0, -0.2, 0);
|
||||
fromPoint.applyQuaternion(quaternion);
|
||||
fromPoint.add(point);
|
||||
toPoint.set(0, -point.y, 0);
|
||||
toPoint.applyQuaternion(quaternion);
|
||||
toPoint.add(point);
|
||||
extrudeShape(tube3, fromPoint, toPoint);
|
||||
}
|
||||
}
|
||||
this.setAttribute("position", new BufferAttribute(new Float32Array(vertices), 3));
|
||||
this.setAttribute("normal", new BufferAttribute(new Float32Array(normals), 3));
|
||||
}
|
||||
}
|
||||
class RollerCoasterShadowGeometry extends BufferGeometry {
|
||||
constructor(curve, divisions) {
|
||||
super();
|
||||
const vertices = [];
|
||||
const up = new Vector3(0, 1, 0);
|
||||
const forward = new Vector3();
|
||||
const quaternion = new Quaternion();
|
||||
const prevQuaternion = new Quaternion();
|
||||
prevQuaternion.setFromAxisAngle(up, Math.PI / 2);
|
||||
const point = new Vector3();
|
||||
const prevPoint = new Vector3();
|
||||
prevPoint.copy(curve.getPointAt(0));
|
||||
prevPoint.y = 0;
|
||||
const vector1 = new Vector3();
|
||||
const vector2 = new Vector3();
|
||||
const vector3 = new Vector3();
|
||||
const vector4 = new Vector3();
|
||||
for (let i = 1; i <= divisions; i++) {
|
||||
point.copy(curve.getPointAt(i / divisions));
|
||||
point.y = 0;
|
||||
forward.subVectors(point, prevPoint);
|
||||
const angle = Math.atan2(forward.x, forward.z);
|
||||
quaternion.setFromAxisAngle(up, angle);
|
||||
vector1.set(-0.3, 0, 0);
|
||||
vector1.applyQuaternion(quaternion);
|
||||
vector1.add(point);
|
||||
vector2.set(0.3, 0, 0);
|
||||
vector2.applyQuaternion(quaternion);
|
||||
vector2.add(point);
|
||||
vector3.set(0.3, 0, 0);
|
||||
vector3.applyQuaternion(prevQuaternion);
|
||||
vector3.add(prevPoint);
|
||||
vector4.set(-0.3, 0, 0);
|
||||
vector4.applyQuaternion(prevQuaternion);
|
||||
vector4.add(prevPoint);
|
||||
vertices.push(vector1.x, vector1.y, vector1.z);
|
||||
vertices.push(vector2.x, vector2.y, vector2.z);
|
||||
vertices.push(vector4.x, vector4.y, vector4.z);
|
||||
vertices.push(vector2.x, vector2.y, vector2.z);
|
||||
vertices.push(vector3.x, vector3.y, vector3.z);
|
||||
vertices.push(vector4.x, vector4.y, vector4.z);
|
||||
prevPoint.copy(point);
|
||||
prevQuaternion.copy(quaternion);
|
||||
}
|
||||
this.setAttribute("position", new BufferAttribute(new Float32Array(vertices), 3));
|
||||
}
|
||||
}
|
||||
class SkyGeometry extends BufferGeometry {
|
||||
constructor() {
|
||||
super();
|
||||
const vertices = [];
|
||||
for (let i = 0; i < 100; i++) {
|
||||
const x = Math.random() * 800 - 400;
|
||||
const y = Math.random() * 50 + 50;
|
||||
const z = Math.random() * 800 - 400;
|
||||
const size = Math.random() * 40 + 20;
|
||||
vertices.push(x - size, y, z - size);
|
||||
vertices.push(x + size, y, z - size);
|
||||
vertices.push(x - size, y, z + size);
|
||||
vertices.push(x + size, y, z - size);
|
||||
vertices.push(x + size, y, z + size);
|
||||
vertices.push(x - size, y, z + size);
|
||||
}
|
||||
this.setAttribute("position", new BufferAttribute(new Float32Array(vertices), 3));
|
||||
}
|
||||
}
|
||||
class TreesGeometry extends BufferGeometry {
|
||||
constructor(landscape) {
|
||||
super();
|
||||
const vertices = [];
|
||||
const colors = [];
|
||||
const raycaster = new Raycaster();
|
||||
raycaster.ray.direction.set(0, -1, 0);
|
||||
const _color = new Color();
|
||||
for (let i = 0; i < 2e3; i++) {
|
||||
const x = Math.random() * 500 - 250;
|
||||
const z = Math.random() * 500 - 250;
|
||||
raycaster.ray.origin.set(x, 50, z);
|
||||
const intersections = raycaster.intersectObject(landscape);
|
||||
if (intersections.length === 0)
|
||||
continue;
|
||||
const y = intersections[0].point.y;
|
||||
const height = Math.random() * 5 + 0.5;
|
||||
let angle = Math.random() * Math.PI * 2;
|
||||
vertices.push(x + Math.sin(angle), y, z + Math.cos(angle));
|
||||
vertices.push(x, y + height, z);
|
||||
vertices.push(x + Math.sin(angle + Math.PI), y, z + Math.cos(angle + Math.PI));
|
||||
angle += Math.PI / 2;
|
||||
vertices.push(x + Math.sin(angle), y, z + Math.cos(angle));
|
||||
vertices.push(x, y + height, z);
|
||||
vertices.push(x + Math.sin(angle + Math.PI), y, z + Math.cos(angle + Math.PI));
|
||||
const random = Math.random() * 0.1;
|
||||
for (let j = 0; j < 6; j++) {
|
||||
_color.setRGB(0.2 + random, 0.4 + random, 0, "srgb");
|
||||
colors.push(_color.r, _color.g, _color.b);
|
||||
}
|
||||
}
|
||||
this.setAttribute("position", new BufferAttribute(new Float32Array(vertices), 3));
|
||||
this.setAttribute("color", new BufferAttribute(new Float32Array(colors), 3));
|
||||
}
|
||||
}
|
||||
export {
|
||||
RollerCoasterGeometry,
|
||||
RollerCoasterLiftersGeometry,
|
||||
RollerCoasterShadowGeometry,
|
||||
SkyGeometry,
|
||||
TreesGeometry
|
||||
};
|
||||
//# sourceMappingURL=RollerCoaster.js.map
|
||||
1
node_modules/three-stdlib/misc/RollerCoaster.js.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/RollerCoaster.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
102
node_modules/three-stdlib/misc/Timer.cjs
generated
vendored
Normal file
102
node_modules/three-stdlib/misc/Timer.cjs
generated
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
||||
var __publicField = (obj, key, value) => {
|
||||
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
||||
return value;
|
||||
};
|
||||
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
||||
class Timer {
|
||||
constructor() {
|
||||
__publicField(this, "_previousTime");
|
||||
__publicField(this, "_currentTime");
|
||||
__publicField(this, "_delta");
|
||||
__publicField(this, "_elapsed");
|
||||
__publicField(this, "_timescale");
|
||||
__publicField(this, "_useFixedDelta");
|
||||
__publicField(this, "_fixedDelta");
|
||||
__publicField(this, "_usePageVisibilityAPI");
|
||||
__publicField(this, "_pageVisibilityHandler");
|
||||
this._previousTime = 0;
|
||||
this._currentTime = 0;
|
||||
this._delta = 0;
|
||||
this._elapsed = 0;
|
||||
this._timescale = 1;
|
||||
this._useFixedDelta = false;
|
||||
this._fixedDelta = 16.67;
|
||||
this._usePageVisibilityAPI = typeof document !== "undefined" && document.hidden !== void 0;
|
||||
}
|
||||
// https://github.com/mrdoob/three.js/issues/20575
|
||||
// use Page Visibility API to avoid large time delta values
|
||||
connect() {
|
||||
if (this._usePageVisibilityAPI) {
|
||||
this._pageVisibilityHandler = handleVisibilityChange.bind(this);
|
||||
document.addEventListener("visibilitychange", this._pageVisibilityHandler, false);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
dispose() {
|
||||
if (this._usePageVisibilityAPI && this._pageVisibilityHandler) {
|
||||
document.removeEventListener("visibilitychange", this._pageVisibilityHandler);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
disableFixedDelta() {
|
||||
this._useFixedDelta = false;
|
||||
return this;
|
||||
}
|
||||
enableFixedDelta() {
|
||||
this._useFixedDelta = true;
|
||||
return this;
|
||||
}
|
||||
getDelta() {
|
||||
return this._delta / 1e3;
|
||||
}
|
||||
getElapsedTime() {
|
||||
return this._elapsed / 1e3;
|
||||
}
|
||||
getFixedDelta() {
|
||||
return this._fixedDelta / 1e3;
|
||||
}
|
||||
getTimescale() {
|
||||
return this._timescale;
|
||||
}
|
||||
reset() {
|
||||
this._currentTime = this._now();
|
||||
return this;
|
||||
}
|
||||
setFixedDelta(fixedDelta) {
|
||||
this._fixedDelta = fixedDelta * 1e3;
|
||||
return this;
|
||||
}
|
||||
setTimescale(timescale) {
|
||||
this._timescale = timescale;
|
||||
return this;
|
||||
}
|
||||
update() {
|
||||
if (this._useFixedDelta === true) {
|
||||
this._delta = this._fixedDelta;
|
||||
} else {
|
||||
this._previousTime = this._currentTime;
|
||||
this._currentTime = this._now();
|
||||
this._delta = this._currentTime - this._previousTime;
|
||||
}
|
||||
this._delta *= this._timescale;
|
||||
this._elapsed += this._delta;
|
||||
return this;
|
||||
}
|
||||
// For THREE.Clock backward compatibility
|
||||
get elapsedTime() {
|
||||
return this.getElapsedTime();
|
||||
}
|
||||
// private
|
||||
_now() {
|
||||
return (typeof performance === "undefined" ? Date : performance).now();
|
||||
}
|
||||
}
|
||||
function handleVisibilityChange() {
|
||||
if (document.hidden === false)
|
||||
this.reset();
|
||||
}
|
||||
exports.Timer = Timer;
|
||||
//# sourceMappingURL=Timer.cjs.map
|
||||
1
node_modules/three-stdlib/misc/Timer.cjs.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/Timer.cjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"Timer.cjs","sources":["../../src/misc/Timer.ts"],"sourcesContent":["class Timer {\n private _previousTime: number\n private _currentTime: number\n private _delta: number\n private _elapsed: number\n private _timescale: number\n private _useFixedDelta: boolean\n private _fixedDelta: number\n private _usePageVisibilityAPI: boolean\n private _pageVisibilityHandler: ((...args: any[]) => void) | undefined\n\n constructor() {\n this._previousTime = 0\n this._currentTime = 0\n this._delta = 0\n this._elapsed = 0\n this._timescale = 1\n this._useFixedDelta = false\n this._fixedDelta = 16.67 // ms, corresponds to approx. 60 FPS\n this._usePageVisibilityAPI = typeof document !== 'undefined' && document.hidden !== undefined\n }\n\n // https://github.com/mrdoob/three.js/issues/20575\n // use Page Visibility API to avoid large time delta values\n connect(): this {\n if (this._usePageVisibilityAPI) {\n this._pageVisibilityHandler = handleVisibilityChange.bind(this)\n document.addEventListener('visibilitychange', this._pageVisibilityHandler, false)\n }\n return this\n }\n\n dispose(): this {\n if (this._usePageVisibilityAPI && this._pageVisibilityHandler) {\n document.removeEventListener('visibilitychange', this._pageVisibilityHandler)\n }\n return this\n }\n\n disableFixedDelta(): this {\n this._useFixedDelta = false\n return this\n }\n\n enableFixedDelta(): this {\n this._useFixedDelta = true\n return this\n }\n\n getDelta(): number {\n return this._delta / 1000\n }\n\n getElapsedTime(): number {\n return this._elapsed / 1000\n }\n\n getFixedDelta(): number {\n return this._fixedDelta / 1000\n }\n\n getTimescale(): number {\n return this._timescale\n }\n\n reset(): this {\n this._currentTime = this._now()\n return this\n }\n\n setFixedDelta(fixedDelta: number): this {\n this._fixedDelta = fixedDelta * 1000\n return this\n }\n\n setTimescale(timescale: number): this {\n this._timescale = timescale\n return this\n }\n\n update(): this {\n if (this._useFixedDelta === true) {\n this._delta = this._fixedDelta\n } else {\n this._previousTime = this._currentTime\n this._currentTime = this._now()\n this._delta = this._currentTime - this._previousTime\n }\n this._delta *= this._timescale\n this._elapsed += this._delta // _elapsed is the accumulation of all previous deltas\n return this\n }\n\n // For THREE.Clock backward compatibility\n get elapsedTime(): number {\n return this.getElapsedTime()\n }\n\n // private\n\n private _now(): number {\n return (typeof performance === 'undefined' ? Date : performance).now()\n }\n}\n\nfunction handleVisibilityChange(this: Timer): void {\n if (document.hidden === false) this.reset()\n}\n\nexport { Timer }\n"],"names":[],"mappings":";;;;;;;;AAAA,MAAM,MAAM;AAAA,EAWV,cAAc;AAVN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGN,SAAK,gBAAgB;AACrB,SAAK,eAAe;AACpB,SAAK,SAAS;AACd,SAAK,WAAW;AAChB,SAAK,aAAa;AAClB,SAAK,iBAAiB;AACtB,SAAK,cAAc;AACnB,SAAK,wBAAwB,OAAO,aAAa,eAAe,SAAS,WAAW;AAAA,EACtF;AAAA;AAAA;AAAA,EAIA,UAAgB;AACd,QAAI,KAAK,uBAAuB;AACzB,WAAA,yBAAyB,uBAAuB,KAAK,IAAI;AAC9D,eAAS,iBAAiB,oBAAoB,KAAK,wBAAwB,KAAK;AAAA,IAClF;AACO,WAAA;AAAA,EACT;AAAA,EAEA,UAAgB;AACV,QAAA,KAAK,yBAAyB,KAAK,wBAAwB;AACpD,eAAA,oBAAoB,oBAAoB,KAAK,sBAAsB;AAAA,IAC9E;AACO,WAAA;AAAA,EACT;AAAA,EAEA,oBAA0B;AACxB,SAAK,iBAAiB;AACf,WAAA;AAAA,EACT;AAAA,EAEA,mBAAyB;AACvB,SAAK,iBAAiB;AACf,WAAA;AAAA,EACT;AAAA,EAEA,WAAmB;AACjB,WAAO,KAAK,SAAS;AAAA,EACvB;AAAA,EAEA,iBAAyB;AACvB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,gBAAwB;AACtB,WAAO,KAAK,cAAc;AAAA,EAC5B;AAAA,EAEA,eAAuB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,QAAc;AACP,SAAA,eAAe,KAAK;AAClB,WAAA;AAAA,EACT;AAAA,EAEA,cAAc,YAA0B;AACtC,SAAK,cAAc,aAAa;AACzB,WAAA;AAAA,EACT;AAAA,EAEA,aAAa,WAAyB;AACpC,SAAK,aAAa;AACX,WAAA;AAAA,EACT;AAAA,EAEA,SAAe;AACT,QAAA,KAAK,mBAAmB,MAAM;AAChC,WAAK,SAAS,KAAK;AAAA,IAAA,OACd;AACL,WAAK,gBAAgB,KAAK;AACrB,WAAA,eAAe,KAAK;AACpB,WAAA,SAAS,KAAK,eAAe,KAAK;AAAA,IACzC;AACA,SAAK,UAAU,KAAK;AACpB,SAAK,YAAY,KAAK;AACf,WAAA;AAAA,EACT;AAAA;AAAA,EAGA,IAAI,cAAsB;AACxB,WAAO,KAAK;EACd;AAAA;AAAA,EAIQ,OAAe;AACrB,YAAQ,OAAO,gBAAgB,cAAc,OAAO,aAAa;EACnE;AACF;AAEA,SAAS,yBAA0C;AACjD,MAAI,SAAS,WAAW;AAAO,SAAK,MAAM;AAC5C;;"}
|
||||
27
node_modules/three-stdlib/misc/Timer.d.ts
generated
vendored
Normal file
27
node_modules/three-stdlib/misc/Timer.d.ts
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
declare class Timer {
|
||||
private _previousTime;
|
||||
private _currentTime;
|
||||
private _delta;
|
||||
private _elapsed;
|
||||
private _timescale;
|
||||
private _useFixedDelta;
|
||||
private _fixedDelta;
|
||||
private _usePageVisibilityAPI;
|
||||
private _pageVisibilityHandler;
|
||||
constructor();
|
||||
connect(): this;
|
||||
dispose(): this;
|
||||
disableFixedDelta(): this;
|
||||
enableFixedDelta(): this;
|
||||
getDelta(): number;
|
||||
getElapsedTime(): number;
|
||||
getFixedDelta(): number;
|
||||
getTimescale(): number;
|
||||
reset(): this;
|
||||
setFixedDelta(fixedDelta: number): this;
|
||||
setTimescale(timescale: number): this;
|
||||
update(): this;
|
||||
get elapsedTime(): number;
|
||||
private _now;
|
||||
}
|
||||
export { Timer };
|
||||
102
node_modules/three-stdlib/misc/Timer.js
generated
vendored
Normal file
102
node_modules/three-stdlib/misc/Timer.js
generated
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
var __defProp = Object.defineProperty;
|
||||
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
||||
var __publicField = (obj, key, value) => {
|
||||
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
||||
return value;
|
||||
};
|
||||
class Timer {
|
||||
constructor() {
|
||||
__publicField(this, "_previousTime");
|
||||
__publicField(this, "_currentTime");
|
||||
__publicField(this, "_delta");
|
||||
__publicField(this, "_elapsed");
|
||||
__publicField(this, "_timescale");
|
||||
__publicField(this, "_useFixedDelta");
|
||||
__publicField(this, "_fixedDelta");
|
||||
__publicField(this, "_usePageVisibilityAPI");
|
||||
__publicField(this, "_pageVisibilityHandler");
|
||||
this._previousTime = 0;
|
||||
this._currentTime = 0;
|
||||
this._delta = 0;
|
||||
this._elapsed = 0;
|
||||
this._timescale = 1;
|
||||
this._useFixedDelta = false;
|
||||
this._fixedDelta = 16.67;
|
||||
this._usePageVisibilityAPI = typeof document !== "undefined" && document.hidden !== void 0;
|
||||
}
|
||||
// https://github.com/mrdoob/three.js/issues/20575
|
||||
// use Page Visibility API to avoid large time delta values
|
||||
connect() {
|
||||
if (this._usePageVisibilityAPI) {
|
||||
this._pageVisibilityHandler = handleVisibilityChange.bind(this);
|
||||
document.addEventListener("visibilitychange", this._pageVisibilityHandler, false);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
dispose() {
|
||||
if (this._usePageVisibilityAPI && this._pageVisibilityHandler) {
|
||||
document.removeEventListener("visibilitychange", this._pageVisibilityHandler);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
disableFixedDelta() {
|
||||
this._useFixedDelta = false;
|
||||
return this;
|
||||
}
|
||||
enableFixedDelta() {
|
||||
this._useFixedDelta = true;
|
||||
return this;
|
||||
}
|
||||
getDelta() {
|
||||
return this._delta / 1e3;
|
||||
}
|
||||
getElapsedTime() {
|
||||
return this._elapsed / 1e3;
|
||||
}
|
||||
getFixedDelta() {
|
||||
return this._fixedDelta / 1e3;
|
||||
}
|
||||
getTimescale() {
|
||||
return this._timescale;
|
||||
}
|
||||
reset() {
|
||||
this._currentTime = this._now();
|
||||
return this;
|
||||
}
|
||||
setFixedDelta(fixedDelta) {
|
||||
this._fixedDelta = fixedDelta * 1e3;
|
||||
return this;
|
||||
}
|
||||
setTimescale(timescale) {
|
||||
this._timescale = timescale;
|
||||
return this;
|
||||
}
|
||||
update() {
|
||||
if (this._useFixedDelta === true) {
|
||||
this._delta = this._fixedDelta;
|
||||
} else {
|
||||
this._previousTime = this._currentTime;
|
||||
this._currentTime = this._now();
|
||||
this._delta = this._currentTime - this._previousTime;
|
||||
}
|
||||
this._delta *= this._timescale;
|
||||
this._elapsed += this._delta;
|
||||
return this;
|
||||
}
|
||||
// For THREE.Clock backward compatibility
|
||||
get elapsedTime() {
|
||||
return this.getElapsedTime();
|
||||
}
|
||||
// private
|
||||
_now() {
|
||||
return (typeof performance === "undefined" ? Date : performance).now();
|
||||
}
|
||||
}
|
||||
function handleVisibilityChange() {
|
||||
if (document.hidden === false)
|
||||
this.reset();
|
||||
}
|
||||
export {
|
||||
Timer
|
||||
};
|
||||
//# sourceMappingURL=Timer.js.map
|
||||
1
node_modules/three-stdlib/misc/Timer.js.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/Timer.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"Timer.js","sources":["../../src/misc/Timer.ts"],"sourcesContent":["class Timer {\n private _previousTime: number\n private _currentTime: number\n private _delta: number\n private _elapsed: number\n private _timescale: number\n private _useFixedDelta: boolean\n private _fixedDelta: number\n private _usePageVisibilityAPI: boolean\n private _pageVisibilityHandler: ((...args: any[]) => void) | undefined\n\n constructor() {\n this._previousTime = 0\n this._currentTime = 0\n this._delta = 0\n this._elapsed = 0\n this._timescale = 1\n this._useFixedDelta = false\n this._fixedDelta = 16.67 // ms, corresponds to approx. 60 FPS\n this._usePageVisibilityAPI = typeof document !== 'undefined' && document.hidden !== undefined\n }\n\n // https://github.com/mrdoob/three.js/issues/20575\n // use Page Visibility API to avoid large time delta values\n connect(): this {\n if (this._usePageVisibilityAPI) {\n this._pageVisibilityHandler = handleVisibilityChange.bind(this)\n document.addEventListener('visibilitychange', this._pageVisibilityHandler, false)\n }\n return this\n }\n\n dispose(): this {\n if (this._usePageVisibilityAPI && this._pageVisibilityHandler) {\n document.removeEventListener('visibilitychange', this._pageVisibilityHandler)\n }\n return this\n }\n\n disableFixedDelta(): this {\n this._useFixedDelta = false\n return this\n }\n\n enableFixedDelta(): this {\n this._useFixedDelta = true\n return this\n }\n\n getDelta(): number {\n return this._delta / 1000\n }\n\n getElapsedTime(): number {\n return this._elapsed / 1000\n }\n\n getFixedDelta(): number {\n return this._fixedDelta / 1000\n }\n\n getTimescale(): number {\n return this._timescale\n }\n\n reset(): this {\n this._currentTime = this._now()\n return this\n }\n\n setFixedDelta(fixedDelta: number): this {\n this._fixedDelta = fixedDelta * 1000\n return this\n }\n\n setTimescale(timescale: number): this {\n this._timescale = timescale\n return this\n }\n\n update(): this {\n if (this._useFixedDelta === true) {\n this._delta = this._fixedDelta\n } else {\n this._previousTime = this._currentTime\n this._currentTime = this._now()\n this._delta = this._currentTime - this._previousTime\n }\n this._delta *= this._timescale\n this._elapsed += this._delta // _elapsed is the accumulation of all previous deltas\n return this\n }\n\n // For THREE.Clock backward compatibility\n get elapsedTime(): number {\n return this.getElapsedTime()\n }\n\n // private\n\n private _now(): number {\n return (typeof performance === 'undefined' ? Date : performance).now()\n }\n}\n\nfunction handleVisibilityChange(this: Timer): void {\n if (document.hidden === false) this.reset()\n}\n\nexport { Timer }\n"],"names":[],"mappings":";;;;;;AAAA,MAAM,MAAM;AAAA,EAWV,cAAc;AAVN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGN,SAAK,gBAAgB;AACrB,SAAK,eAAe;AACpB,SAAK,SAAS;AACd,SAAK,WAAW;AAChB,SAAK,aAAa;AAClB,SAAK,iBAAiB;AACtB,SAAK,cAAc;AACnB,SAAK,wBAAwB,OAAO,aAAa,eAAe,SAAS,WAAW;AAAA,EACtF;AAAA;AAAA;AAAA,EAIA,UAAgB;AACd,QAAI,KAAK,uBAAuB;AACzB,WAAA,yBAAyB,uBAAuB,KAAK,IAAI;AAC9D,eAAS,iBAAiB,oBAAoB,KAAK,wBAAwB,KAAK;AAAA,IAClF;AACO,WAAA;AAAA,EACT;AAAA,EAEA,UAAgB;AACV,QAAA,KAAK,yBAAyB,KAAK,wBAAwB;AACpD,eAAA,oBAAoB,oBAAoB,KAAK,sBAAsB;AAAA,IAC9E;AACO,WAAA;AAAA,EACT;AAAA,EAEA,oBAA0B;AACxB,SAAK,iBAAiB;AACf,WAAA;AAAA,EACT;AAAA,EAEA,mBAAyB;AACvB,SAAK,iBAAiB;AACf,WAAA;AAAA,EACT;AAAA,EAEA,WAAmB;AACjB,WAAO,KAAK,SAAS;AAAA,EACvB;AAAA,EAEA,iBAAyB;AACvB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,gBAAwB;AACtB,WAAO,KAAK,cAAc;AAAA,EAC5B;AAAA,EAEA,eAAuB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,QAAc;AACP,SAAA,eAAe,KAAK;AAClB,WAAA;AAAA,EACT;AAAA,EAEA,cAAc,YAA0B;AACtC,SAAK,cAAc,aAAa;AACzB,WAAA;AAAA,EACT;AAAA,EAEA,aAAa,WAAyB;AACpC,SAAK,aAAa;AACX,WAAA;AAAA,EACT;AAAA,EAEA,SAAe;AACT,QAAA,KAAK,mBAAmB,MAAM;AAChC,WAAK,SAAS,KAAK;AAAA,IAAA,OACd;AACL,WAAK,gBAAgB,KAAK;AACrB,WAAA,eAAe,KAAK;AACpB,WAAA,SAAS,KAAK,eAAe,KAAK;AAAA,IACzC;AACA,SAAK,UAAU,KAAK;AACpB,SAAK,YAAY,KAAK;AACf,WAAA;AAAA,EACT;AAAA;AAAA,EAGA,IAAI,cAAsB;AACxB,WAAO,KAAK;EACd;AAAA;AAAA,EAIQ,OAAe;AACrB,YAAQ,OAAO,gBAAgB,cAAc,OAAO,aAAa;EACnE;AACF;AAEA,SAAS,yBAA0C;AACjD,MAAI,SAAS,WAAW;AAAO,SAAK,MAAM;AAC5C;"}
|
||||
124
node_modules/three-stdlib/misc/TubePainter.cjs
generated
vendored
Normal file
124
node_modules/three-stdlib/misc/TubePainter.cjs
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
||||
const THREE = require("three");
|
||||
function TubePainter() {
|
||||
const BUFFER_SIZE = 1e6 * 3;
|
||||
const positions = new THREE.BufferAttribute(new Float32Array(BUFFER_SIZE), 3);
|
||||
positions.usage = THREE.DynamicDrawUsage;
|
||||
const normals = new THREE.BufferAttribute(new Float32Array(BUFFER_SIZE), 3);
|
||||
normals.usage = THREE.DynamicDrawUsage;
|
||||
const colors = new THREE.BufferAttribute(new Float32Array(BUFFER_SIZE), 3);
|
||||
colors.usage = THREE.DynamicDrawUsage;
|
||||
const geometry = new THREE.BufferGeometry();
|
||||
geometry.setAttribute("position", positions);
|
||||
geometry.setAttribute("normal", normals);
|
||||
geometry.setAttribute("color", colors);
|
||||
geometry.drawRange.count = 0;
|
||||
const material = new THREE.MeshStandardMaterial({
|
||||
vertexColors: true
|
||||
});
|
||||
const mesh = new THREE.Mesh(geometry, material);
|
||||
mesh.frustumCulled = false;
|
||||
function getPoints(size2) {
|
||||
const PI2 = Math.PI * 2;
|
||||
const sides = 10;
|
||||
const array = [];
|
||||
const radius = 0.01 * size2;
|
||||
for (let i = 0; i < sides; i++) {
|
||||
const angle = i / sides * PI2;
|
||||
array.push(new THREE.Vector3(Math.sin(angle) * radius, Math.cos(angle) * radius, 0));
|
||||
}
|
||||
return array;
|
||||
}
|
||||
const vector1 = new THREE.Vector3();
|
||||
const vector2 = new THREE.Vector3();
|
||||
const vector3 = new THREE.Vector3();
|
||||
const vector4 = new THREE.Vector3();
|
||||
const color = new THREE.Color(16777215);
|
||||
let size = 1;
|
||||
function stroke(position1, position2, matrix12, matrix22) {
|
||||
if (position1.distanceToSquared(position2) === 0)
|
||||
return;
|
||||
let count2 = geometry.drawRange.count;
|
||||
const points = getPoints(size);
|
||||
for (let i = 0, il = points.length; i < il; i++) {
|
||||
const vertex1 = points[i];
|
||||
const vertex2 = points[(i + 1) % il];
|
||||
vector1.copy(vertex1).applyMatrix4(matrix22).add(position2);
|
||||
vector2.copy(vertex2).applyMatrix4(matrix22).add(position2);
|
||||
vector3.copy(vertex2).applyMatrix4(matrix12).add(position1);
|
||||
vector4.copy(vertex1).applyMatrix4(matrix12).add(position1);
|
||||
vector1.toArray(positions.array, (count2 + 0) * 3);
|
||||
vector2.toArray(positions.array, (count2 + 1) * 3);
|
||||
vector4.toArray(positions.array, (count2 + 2) * 3);
|
||||
vector2.toArray(positions.array, (count2 + 3) * 3);
|
||||
vector3.toArray(positions.array, (count2 + 4) * 3);
|
||||
vector4.toArray(positions.array, (count2 + 5) * 3);
|
||||
vector1.copy(vertex1).applyMatrix4(matrix22).normalize();
|
||||
vector2.copy(vertex2).applyMatrix4(matrix22).normalize();
|
||||
vector3.copy(vertex2).applyMatrix4(matrix12).normalize();
|
||||
vector4.copy(vertex1).applyMatrix4(matrix12).normalize();
|
||||
vector1.toArray(normals.array, (count2 + 0) * 3);
|
||||
vector2.toArray(normals.array, (count2 + 1) * 3);
|
||||
vector4.toArray(normals.array, (count2 + 2) * 3);
|
||||
vector2.toArray(normals.array, (count2 + 3) * 3);
|
||||
vector3.toArray(normals.array, (count2 + 4) * 3);
|
||||
vector4.toArray(normals.array, (count2 + 5) * 3);
|
||||
color.toArray(colors.array, (count2 + 0) * 3);
|
||||
color.toArray(colors.array, (count2 + 1) * 3);
|
||||
color.toArray(colors.array, (count2 + 2) * 3);
|
||||
color.toArray(colors.array, (count2 + 3) * 3);
|
||||
color.toArray(colors.array, (count2 + 4) * 3);
|
||||
color.toArray(colors.array, (count2 + 5) * 3);
|
||||
count2 += 6;
|
||||
}
|
||||
geometry.drawRange.count = count2;
|
||||
}
|
||||
const up = new THREE.Vector3(0, 1, 0);
|
||||
const point1 = new THREE.Vector3();
|
||||
const point2 = new THREE.Vector3();
|
||||
const matrix1 = new THREE.Matrix4();
|
||||
const matrix2 = new THREE.Matrix4();
|
||||
function moveTo(position) {
|
||||
point1.copy(position);
|
||||
matrix1.lookAt(point2, point1, up);
|
||||
point2.copy(position);
|
||||
matrix2.copy(matrix1);
|
||||
}
|
||||
function lineTo(position) {
|
||||
point1.copy(position);
|
||||
matrix1.lookAt(point2, point1, up);
|
||||
stroke(point1, point2, matrix1, matrix2);
|
||||
point2.copy(point1);
|
||||
matrix2.copy(matrix1);
|
||||
}
|
||||
function setSize(value) {
|
||||
size = value;
|
||||
}
|
||||
let count = 0;
|
||||
function update() {
|
||||
const start = count;
|
||||
const end = geometry.drawRange.count;
|
||||
if (start === end)
|
||||
return;
|
||||
positions.updateRange.offset = start * 3;
|
||||
positions.updateRange.count = (end - start) * 3;
|
||||
positions.needsUpdate = true;
|
||||
normals.updateRange.offset = start * 3;
|
||||
normals.updateRange.count = (end - start) * 3;
|
||||
normals.needsUpdate = true;
|
||||
colors.updateRange.offset = start * 3;
|
||||
colors.updateRange.count = (end - start) * 3;
|
||||
colors.needsUpdate = true;
|
||||
count = geometry.drawRange.count;
|
||||
}
|
||||
return {
|
||||
mesh,
|
||||
moveTo,
|
||||
lineTo,
|
||||
setSize,
|
||||
update
|
||||
};
|
||||
}
|
||||
exports.TubePainter = TubePainter;
|
||||
//# sourceMappingURL=TubePainter.cjs.map
|
||||
1
node_modules/three-stdlib/misc/TubePainter.cjs.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/TubePainter.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
10
node_modules/three-stdlib/misc/TubePainter.d.ts
generated
vendored
Normal file
10
node_modules/three-stdlib/misc/TubePainter.d.ts
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Matrix4, Mesh, Vector3 } from 'three'
|
||||
|
||||
export class TubePainter {
|
||||
constructor()
|
||||
|
||||
mesh: Mesh
|
||||
|
||||
stroke(position1: Vector3, position2: Vector3, matrix1: Matrix4, matrix2: Matrix4): void
|
||||
updateGeometry(start: number, end: number): void
|
||||
}
|
||||
124
node_modules/three-stdlib/misc/TubePainter.js
generated
vendored
Normal file
124
node_modules/three-stdlib/misc/TubePainter.js
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
import { BufferAttribute, DynamicDrawUsage, BufferGeometry, MeshStandardMaterial, Mesh, Vector3, Color, Matrix4 } from "three";
|
||||
function TubePainter() {
|
||||
const BUFFER_SIZE = 1e6 * 3;
|
||||
const positions = new BufferAttribute(new Float32Array(BUFFER_SIZE), 3);
|
||||
positions.usage = DynamicDrawUsage;
|
||||
const normals = new BufferAttribute(new Float32Array(BUFFER_SIZE), 3);
|
||||
normals.usage = DynamicDrawUsage;
|
||||
const colors = new BufferAttribute(new Float32Array(BUFFER_SIZE), 3);
|
||||
colors.usage = DynamicDrawUsage;
|
||||
const geometry = new BufferGeometry();
|
||||
geometry.setAttribute("position", positions);
|
||||
geometry.setAttribute("normal", normals);
|
||||
geometry.setAttribute("color", colors);
|
||||
geometry.drawRange.count = 0;
|
||||
const material = new MeshStandardMaterial({
|
||||
vertexColors: true
|
||||
});
|
||||
const mesh = new Mesh(geometry, material);
|
||||
mesh.frustumCulled = false;
|
||||
function getPoints(size2) {
|
||||
const PI2 = Math.PI * 2;
|
||||
const sides = 10;
|
||||
const array = [];
|
||||
const radius = 0.01 * size2;
|
||||
for (let i = 0; i < sides; i++) {
|
||||
const angle = i / sides * PI2;
|
||||
array.push(new Vector3(Math.sin(angle) * radius, Math.cos(angle) * radius, 0));
|
||||
}
|
||||
return array;
|
||||
}
|
||||
const vector1 = new Vector3();
|
||||
const vector2 = new Vector3();
|
||||
const vector3 = new Vector3();
|
||||
const vector4 = new Vector3();
|
||||
const color = new Color(16777215);
|
||||
let size = 1;
|
||||
function stroke(position1, position2, matrix12, matrix22) {
|
||||
if (position1.distanceToSquared(position2) === 0)
|
||||
return;
|
||||
let count2 = geometry.drawRange.count;
|
||||
const points = getPoints(size);
|
||||
for (let i = 0, il = points.length; i < il; i++) {
|
||||
const vertex1 = points[i];
|
||||
const vertex2 = points[(i + 1) % il];
|
||||
vector1.copy(vertex1).applyMatrix4(matrix22).add(position2);
|
||||
vector2.copy(vertex2).applyMatrix4(matrix22).add(position2);
|
||||
vector3.copy(vertex2).applyMatrix4(matrix12).add(position1);
|
||||
vector4.copy(vertex1).applyMatrix4(matrix12).add(position1);
|
||||
vector1.toArray(positions.array, (count2 + 0) * 3);
|
||||
vector2.toArray(positions.array, (count2 + 1) * 3);
|
||||
vector4.toArray(positions.array, (count2 + 2) * 3);
|
||||
vector2.toArray(positions.array, (count2 + 3) * 3);
|
||||
vector3.toArray(positions.array, (count2 + 4) * 3);
|
||||
vector4.toArray(positions.array, (count2 + 5) * 3);
|
||||
vector1.copy(vertex1).applyMatrix4(matrix22).normalize();
|
||||
vector2.copy(vertex2).applyMatrix4(matrix22).normalize();
|
||||
vector3.copy(vertex2).applyMatrix4(matrix12).normalize();
|
||||
vector4.copy(vertex1).applyMatrix4(matrix12).normalize();
|
||||
vector1.toArray(normals.array, (count2 + 0) * 3);
|
||||
vector2.toArray(normals.array, (count2 + 1) * 3);
|
||||
vector4.toArray(normals.array, (count2 + 2) * 3);
|
||||
vector2.toArray(normals.array, (count2 + 3) * 3);
|
||||
vector3.toArray(normals.array, (count2 + 4) * 3);
|
||||
vector4.toArray(normals.array, (count2 + 5) * 3);
|
||||
color.toArray(colors.array, (count2 + 0) * 3);
|
||||
color.toArray(colors.array, (count2 + 1) * 3);
|
||||
color.toArray(colors.array, (count2 + 2) * 3);
|
||||
color.toArray(colors.array, (count2 + 3) * 3);
|
||||
color.toArray(colors.array, (count2 + 4) * 3);
|
||||
color.toArray(colors.array, (count2 + 5) * 3);
|
||||
count2 += 6;
|
||||
}
|
||||
geometry.drawRange.count = count2;
|
||||
}
|
||||
const up = new Vector3(0, 1, 0);
|
||||
const point1 = new Vector3();
|
||||
const point2 = new Vector3();
|
||||
const matrix1 = new Matrix4();
|
||||
const matrix2 = new Matrix4();
|
||||
function moveTo(position) {
|
||||
point1.copy(position);
|
||||
matrix1.lookAt(point2, point1, up);
|
||||
point2.copy(position);
|
||||
matrix2.copy(matrix1);
|
||||
}
|
||||
function lineTo(position) {
|
||||
point1.copy(position);
|
||||
matrix1.lookAt(point2, point1, up);
|
||||
stroke(point1, point2, matrix1, matrix2);
|
||||
point2.copy(point1);
|
||||
matrix2.copy(matrix1);
|
||||
}
|
||||
function setSize(value) {
|
||||
size = value;
|
||||
}
|
||||
let count = 0;
|
||||
function update() {
|
||||
const start = count;
|
||||
const end = geometry.drawRange.count;
|
||||
if (start === end)
|
||||
return;
|
||||
positions.updateRange.offset = start * 3;
|
||||
positions.updateRange.count = (end - start) * 3;
|
||||
positions.needsUpdate = true;
|
||||
normals.updateRange.offset = start * 3;
|
||||
normals.updateRange.count = (end - start) * 3;
|
||||
normals.needsUpdate = true;
|
||||
colors.updateRange.offset = start * 3;
|
||||
colors.updateRange.count = (end - start) * 3;
|
||||
colors.needsUpdate = true;
|
||||
count = geometry.drawRange.count;
|
||||
}
|
||||
return {
|
||||
mesh,
|
||||
moveTo,
|
||||
lineTo,
|
||||
setSize,
|
||||
update
|
||||
};
|
||||
}
|
||||
export {
|
||||
TubePainter
|
||||
};
|
||||
//# sourceMappingURL=TubePainter.js.map
|
||||
1
node_modules/three-stdlib/misc/TubePainter.js.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/TubePainter.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
305
node_modules/three-stdlib/misc/Volume.cjs
generated
vendored
Normal file
305
node_modules/three-stdlib/misc/Volume.cjs
generated
vendored
Normal file
@@ -0,0 +1,305 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
||||
const THREE = require("three");
|
||||
const VolumeSlice = require("./VolumeSlice.cjs");
|
||||
class Volume {
|
||||
constructor(xLength, yLength, zLength, type, arrayBuffer) {
|
||||
if (xLength !== void 0) {
|
||||
this.xLength = Number(xLength) || 1;
|
||||
this.yLength = Number(yLength) || 1;
|
||||
this.zLength = Number(zLength) || 1;
|
||||
this.axisOrder = ["x", "y", "z"];
|
||||
switch (type) {
|
||||
case "Uint8":
|
||||
case "uint8":
|
||||
case "uchar":
|
||||
case "unsigned char":
|
||||
case "uint8_t":
|
||||
this.data = new Uint8Array(arrayBuffer);
|
||||
break;
|
||||
case "Int8":
|
||||
case "int8":
|
||||
case "signed char":
|
||||
case "int8_t":
|
||||
this.data = new Int8Array(arrayBuffer);
|
||||
break;
|
||||
case "Int16":
|
||||
case "int16":
|
||||
case "short":
|
||||
case "short int":
|
||||
case "signed short":
|
||||
case "signed short int":
|
||||
case "int16_t":
|
||||
this.data = new Int16Array(arrayBuffer);
|
||||
break;
|
||||
case "Uint16":
|
||||
case "uint16":
|
||||
case "ushort":
|
||||
case "unsigned short":
|
||||
case "unsigned short int":
|
||||
case "uint16_t":
|
||||
this.data = new Uint16Array(arrayBuffer);
|
||||
break;
|
||||
case "Int32":
|
||||
case "int32":
|
||||
case "int":
|
||||
case "signed int":
|
||||
case "int32_t":
|
||||
this.data = new Int32Array(arrayBuffer);
|
||||
break;
|
||||
case "Uint32":
|
||||
case "uint32":
|
||||
case "uint":
|
||||
case "unsigned int":
|
||||
case "uint32_t":
|
||||
this.data = new Uint32Array(arrayBuffer);
|
||||
break;
|
||||
case "longlong":
|
||||
case "long long":
|
||||
case "long long int":
|
||||
case "signed long long":
|
||||
case "signed long long int":
|
||||
case "int64":
|
||||
case "int64_t":
|
||||
case "ulonglong":
|
||||
case "unsigned long long":
|
||||
case "unsigned long long int":
|
||||
case "uint64":
|
||||
case "uint64_t":
|
||||
throw new Error("Error in Volume constructor : this type is not supported in JavaScript");
|
||||
case "Float32":
|
||||
case "float32":
|
||||
case "float":
|
||||
this.data = new Float32Array(arrayBuffer);
|
||||
break;
|
||||
case "Float64":
|
||||
case "float64":
|
||||
case "double":
|
||||
this.data = new Float64Array(arrayBuffer);
|
||||
break;
|
||||
default:
|
||||
this.data = new Uint8Array(arrayBuffer);
|
||||
}
|
||||
if (this.data.length !== this.xLength * this.yLength * this.zLength) {
|
||||
throw new Error("Error in Volume constructor, lengths are not matching arrayBuffer size");
|
||||
}
|
||||
}
|
||||
this.spacing = [1, 1, 1];
|
||||
this.offset = [0, 0, 0];
|
||||
this.matrix = new THREE.Matrix3();
|
||||
this.matrix.identity();
|
||||
let lowerThreshold = -Infinity;
|
||||
Object.defineProperty(this, "lowerThreshold", {
|
||||
get: function() {
|
||||
return lowerThreshold;
|
||||
},
|
||||
set: function(value) {
|
||||
lowerThreshold = value;
|
||||
this.sliceList.forEach(function(slice) {
|
||||
slice.geometryNeedsUpdate = true;
|
||||
});
|
||||
}
|
||||
});
|
||||
let upperThreshold = Infinity;
|
||||
Object.defineProperty(this, "upperThreshold", {
|
||||
get: function() {
|
||||
return upperThreshold;
|
||||
},
|
||||
set: function(value) {
|
||||
upperThreshold = value;
|
||||
this.sliceList.forEach(function(slice) {
|
||||
slice.geometryNeedsUpdate = true;
|
||||
});
|
||||
}
|
||||
});
|
||||
this.sliceList = [];
|
||||
this.segmentation = false;
|
||||
}
|
||||
/**
|
||||
* @member {Function} getData Shortcut for data[access(i,j,k)]
|
||||
* @memberof Volume
|
||||
* @param {number} i First coordinate
|
||||
* @param {number} j Second coordinate
|
||||
* @param {number} k Third coordinate
|
||||
* @returns {number} value in the data array
|
||||
*/
|
||||
getData(i, j, k) {
|
||||
return this.data[k * this.xLength * this.yLength + j * this.xLength + i];
|
||||
}
|
||||
/**
|
||||
* @member {Function} access compute the index in the data array corresponding to the given coordinates in IJK system
|
||||
* @memberof Volume
|
||||
* @param {number} i First coordinate
|
||||
* @param {number} j Second coordinate
|
||||
* @param {number} k Third coordinate
|
||||
* @returns {number} index
|
||||
*/
|
||||
access(i, j, k) {
|
||||
return k * this.xLength * this.yLength + j * this.xLength + i;
|
||||
}
|
||||
/**
|
||||
* @member {Function} reverseAccess Retrieve the IJK coordinates of the voxel corresponding of the given index in the data
|
||||
* @memberof Volume
|
||||
* @param {number} index index of the voxel
|
||||
* @returns {Array} [x,y,z]
|
||||
*/
|
||||
reverseAccess(index) {
|
||||
const z = Math.floor(index / (this.yLength * this.xLength));
|
||||
const y = Math.floor((index - z * this.yLength * this.xLength) / this.xLength);
|
||||
const x = index - z * this.yLength * this.xLength - y * this.xLength;
|
||||
return [x, y, z];
|
||||
}
|
||||
/**
|
||||
* @member {Function} map Apply a function to all the voxels, be careful, the value will be replaced
|
||||
* @memberof Volume
|
||||
* @param {Function} functionToMap A function to apply to every voxel, will be called with the following parameters :
|
||||
* value of the voxel
|
||||
* index of the voxel
|
||||
* the data (TypedArray)
|
||||
* @param {Object} context You can specify a context in which call the function, default if this Volume
|
||||
* @returns {Volume} this
|
||||
*/
|
||||
map(functionToMap, context) {
|
||||
const length = this.data.length;
|
||||
context = context || this;
|
||||
for (let i = 0; i < length; i++) {
|
||||
this.data[i] = functionToMap.call(context, this.data[i], i, this.data);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* @member {Function} extractPerpendicularPlane Compute the orientation of the slice and returns all the information relative to the geometry such as sliceAccess, the plane matrix (orientation and position in RAS coordinate) and the dimensions of the plane in both coordinate system.
|
||||
* @memberof Volume
|
||||
* @param {string} axis the normal axis to the slice 'x' 'y' or 'z'
|
||||
* @param {number} index the index of the slice
|
||||
* @returns {Object} an object containing all the usefull information on the geometry of the slice
|
||||
*/
|
||||
extractPerpendicularPlane(axis, RASIndex) {
|
||||
let firstSpacing, secondSpacing, positionOffset, IJKIndex;
|
||||
const axisInIJK = new THREE.Vector3(), firstDirection = new THREE.Vector3(), secondDirection = new THREE.Vector3(), planeMatrix = new THREE.Matrix4().identity(), volume = this;
|
||||
const dimensions = new THREE.Vector3(this.xLength, this.yLength, this.zLength);
|
||||
switch (axis) {
|
||||
case "x":
|
||||
axisInIJK.set(1, 0, 0);
|
||||
firstDirection.set(0, 0, -1);
|
||||
secondDirection.set(0, -1, 0);
|
||||
firstSpacing = this.spacing[this.axisOrder.indexOf("z")];
|
||||
secondSpacing = this.spacing[this.axisOrder.indexOf("y")];
|
||||
IJKIndex = new THREE.Vector3(RASIndex, 0, 0);
|
||||
planeMatrix.multiply(new THREE.Matrix4().makeRotationY(Math.PI / 2));
|
||||
positionOffset = (volume.RASDimensions[0] - 1) / 2;
|
||||
planeMatrix.setPosition(new THREE.Vector3(RASIndex - positionOffset, 0, 0));
|
||||
break;
|
||||
case "y":
|
||||
axisInIJK.set(0, 1, 0);
|
||||
firstDirection.set(1, 0, 0);
|
||||
secondDirection.set(0, 0, 1);
|
||||
firstSpacing = this.spacing[this.axisOrder.indexOf("x")];
|
||||
secondSpacing = this.spacing[this.axisOrder.indexOf("z")];
|
||||
IJKIndex = new THREE.Vector3(0, RASIndex, 0);
|
||||
planeMatrix.multiply(new THREE.Matrix4().makeRotationX(-Math.PI / 2));
|
||||
positionOffset = (volume.RASDimensions[1] - 1) / 2;
|
||||
planeMatrix.setPosition(new THREE.Vector3(0, RASIndex - positionOffset, 0));
|
||||
break;
|
||||
case "z":
|
||||
default:
|
||||
axisInIJK.set(0, 0, 1);
|
||||
firstDirection.set(1, 0, 0);
|
||||
secondDirection.set(0, -1, 0);
|
||||
firstSpacing = this.spacing[this.axisOrder.indexOf("x")];
|
||||
secondSpacing = this.spacing[this.axisOrder.indexOf("y")];
|
||||
IJKIndex = new THREE.Vector3(0, 0, RASIndex);
|
||||
positionOffset = (volume.RASDimensions[2] - 1) / 2;
|
||||
planeMatrix.setPosition(new THREE.Vector3(0, 0, RASIndex - positionOffset));
|
||||
break;
|
||||
}
|
||||
let iLength, jLength;
|
||||
if (!this.segmentation) {
|
||||
firstDirection.applyMatrix4(volume.inverseMatrix).normalize();
|
||||
secondDirection.applyMatrix4(volume.inverseMatrix).normalize();
|
||||
axisInIJK.applyMatrix4(volume.inverseMatrix).normalize();
|
||||
}
|
||||
firstDirection.arglet = "i";
|
||||
secondDirection.arglet = "j";
|
||||
iLength = Math.floor(Math.abs(firstDirection.dot(dimensions)));
|
||||
jLength = Math.floor(Math.abs(secondDirection.dot(dimensions)));
|
||||
const planeWidth = Math.abs(iLength * firstSpacing);
|
||||
const planeHeight = Math.abs(jLength * secondSpacing);
|
||||
IJKIndex = Math.abs(Math.round(IJKIndex.applyMatrix4(volume.inverseMatrix).dot(axisInIJK)));
|
||||
const base = [new THREE.Vector3(1, 0, 0), new THREE.Vector3(0, 1, 0), new THREE.Vector3(0, 0, 1)];
|
||||
const iDirection = [firstDirection, secondDirection, axisInIJK].find(function(x) {
|
||||
return Math.abs(x.dot(base[0])) > 0.9;
|
||||
});
|
||||
const jDirection = [firstDirection, secondDirection, axisInIJK].find(function(x) {
|
||||
return Math.abs(x.dot(base[1])) > 0.9;
|
||||
});
|
||||
const kDirection = [firstDirection, secondDirection, axisInIJK].find(function(x) {
|
||||
return Math.abs(x.dot(base[2])) > 0.9;
|
||||
});
|
||||
function sliceAccess(i, j) {
|
||||
const si = iDirection === axisInIJK ? IJKIndex : iDirection.arglet === "i" ? i : j;
|
||||
const sj = jDirection === axisInIJK ? IJKIndex : jDirection.arglet === "i" ? i : j;
|
||||
const sk = kDirection === axisInIJK ? IJKIndex : kDirection.arglet === "i" ? i : j;
|
||||
const accessI = iDirection.dot(base[0]) > 0 ? si : volume.xLength - 1 - si;
|
||||
const accessJ = jDirection.dot(base[1]) > 0 ? sj : volume.yLength - 1 - sj;
|
||||
const accessK = kDirection.dot(base[2]) > 0 ? sk : volume.zLength - 1 - sk;
|
||||
return volume.access(accessI, accessJ, accessK);
|
||||
}
|
||||
return {
|
||||
iLength,
|
||||
jLength,
|
||||
sliceAccess,
|
||||
matrix: planeMatrix,
|
||||
planeWidth,
|
||||
planeHeight
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @member {Function} extractSlice Returns a slice corresponding to the given axis and index
|
||||
* The coordinate are given in the Right Anterior Superior coordinate format
|
||||
* @memberof Volume
|
||||
* @param {string} axis the normal axis to the slice 'x' 'y' or 'z'
|
||||
* @param {number} index the index of the slice
|
||||
* @returns {VolumeSlice} the extracted slice
|
||||
*/
|
||||
extractSlice(axis, index) {
|
||||
const slice = new VolumeSlice.VolumeSlice(this, index, axis);
|
||||
this.sliceList.push(slice);
|
||||
return slice;
|
||||
}
|
||||
/**
|
||||
* @member {Function} repaintAllSlices Call repaint on all the slices extracted from this volume
|
||||
* @see VolumeSlice.repaint
|
||||
* @memberof Volume
|
||||
* @returns {Volume} this
|
||||
*/
|
||||
repaintAllSlices() {
|
||||
this.sliceList.forEach(function(slice) {
|
||||
slice.repaint();
|
||||
});
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* @member {Function} computeMinMax Compute the minimum and the maximum of the data in the volume
|
||||
* @memberof Volume
|
||||
* @returns {Array} [min,max]
|
||||
*/
|
||||
computeMinMax() {
|
||||
let min = Infinity;
|
||||
let max = -Infinity;
|
||||
const datasize = this.data.length;
|
||||
let i = 0;
|
||||
for (i = 0; i < datasize; i++) {
|
||||
if (!isNaN(this.data[i])) {
|
||||
const value = this.data[i];
|
||||
min = Math.min(min, value);
|
||||
max = Math.max(max, value);
|
||||
}
|
||||
}
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
return [min, max];
|
||||
}
|
||||
}
|
||||
exports.Volume = Volume;
|
||||
//# sourceMappingURL=Volume.cjs.map
|
||||
1
node_modules/three-stdlib/misc/Volume.cjs.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/Volume.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
37
node_modules/three-stdlib/misc/Volume.d.ts
generated
vendored
Normal file
37
node_modules/three-stdlib/misc/Volume.d.ts
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
import { Matrix3 } from 'three'
|
||||
|
||||
import { VolumeSlice } from './VolumeSlice'
|
||||
|
||||
export class Volume {
|
||||
constructor(xLength?: number, yLength?: number, zLength?: number, type?: string, arrayBuffer?: ArrayLike<number>)
|
||||
|
||||
xLength: number
|
||||
yLength: number
|
||||
zLength: number
|
||||
|
||||
axisOrder: Array<'x' | 'y' | 'z'>
|
||||
|
||||
data: ArrayLike<number>
|
||||
|
||||
spacing: number[]
|
||||
offset: number[]
|
||||
|
||||
matrix: Matrix3
|
||||
|
||||
lowerThreshold: number
|
||||
upperThreshold: number
|
||||
|
||||
sliceList: VolumeSlice[]
|
||||
|
||||
getData(i: number, j: number, k: number): number
|
||||
access(i: number, j: number, k: number): number
|
||||
reverseAccess(index: number): number[]
|
||||
|
||||
map(functionToMap: () => void, context: this): this
|
||||
|
||||
extractPerpendicularPlane(axis: string, RASIndex: number): object
|
||||
extractSlice(axis: string, index: number): VolumeSlice
|
||||
|
||||
repaintAllSlices(): this
|
||||
computeMinMax(): number[]
|
||||
}
|
||||
305
node_modules/three-stdlib/misc/Volume.js
generated
vendored
Normal file
305
node_modules/three-stdlib/misc/Volume.js
generated
vendored
Normal file
@@ -0,0 +1,305 @@
|
||||
import { Matrix3, Vector3, Matrix4 } from "three";
|
||||
import { VolumeSlice } from "./VolumeSlice.js";
|
||||
class Volume {
|
||||
constructor(xLength, yLength, zLength, type, arrayBuffer) {
|
||||
if (xLength !== void 0) {
|
||||
this.xLength = Number(xLength) || 1;
|
||||
this.yLength = Number(yLength) || 1;
|
||||
this.zLength = Number(zLength) || 1;
|
||||
this.axisOrder = ["x", "y", "z"];
|
||||
switch (type) {
|
||||
case "Uint8":
|
||||
case "uint8":
|
||||
case "uchar":
|
||||
case "unsigned char":
|
||||
case "uint8_t":
|
||||
this.data = new Uint8Array(arrayBuffer);
|
||||
break;
|
||||
case "Int8":
|
||||
case "int8":
|
||||
case "signed char":
|
||||
case "int8_t":
|
||||
this.data = new Int8Array(arrayBuffer);
|
||||
break;
|
||||
case "Int16":
|
||||
case "int16":
|
||||
case "short":
|
||||
case "short int":
|
||||
case "signed short":
|
||||
case "signed short int":
|
||||
case "int16_t":
|
||||
this.data = new Int16Array(arrayBuffer);
|
||||
break;
|
||||
case "Uint16":
|
||||
case "uint16":
|
||||
case "ushort":
|
||||
case "unsigned short":
|
||||
case "unsigned short int":
|
||||
case "uint16_t":
|
||||
this.data = new Uint16Array(arrayBuffer);
|
||||
break;
|
||||
case "Int32":
|
||||
case "int32":
|
||||
case "int":
|
||||
case "signed int":
|
||||
case "int32_t":
|
||||
this.data = new Int32Array(arrayBuffer);
|
||||
break;
|
||||
case "Uint32":
|
||||
case "uint32":
|
||||
case "uint":
|
||||
case "unsigned int":
|
||||
case "uint32_t":
|
||||
this.data = new Uint32Array(arrayBuffer);
|
||||
break;
|
||||
case "longlong":
|
||||
case "long long":
|
||||
case "long long int":
|
||||
case "signed long long":
|
||||
case "signed long long int":
|
||||
case "int64":
|
||||
case "int64_t":
|
||||
case "ulonglong":
|
||||
case "unsigned long long":
|
||||
case "unsigned long long int":
|
||||
case "uint64":
|
||||
case "uint64_t":
|
||||
throw new Error("Error in Volume constructor : this type is not supported in JavaScript");
|
||||
case "Float32":
|
||||
case "float32":
|
||||
case "float":
|
||||
this.data = new Float32Array(arrayBuffer);
|
||||
break;
|
||||
case "Float64":
|
||||
case "float64":
|
||||
case "double":
|
||||
this.data = new Float64Array(arrayBuffer);
|
||||
break;
|
||||
default:
|
||||
this.data = new Uint8Array(arrayBuffer);
|
||||
}
|
||||
if (this.data.length !== this.xLength * this.yLength * this.zLength) {
|
||||
throw new Error("Error in Volume constructor, lengths are not matching arrayBuffer size");
|
||||
}
|
||||
}
|
||||
this.spacing = [1, 1, 1];
|
||||
this.offset = [0, 0, 0];
|
||||
this.matrix = new Matrix3();
|
||||
this.matrix.identity();
|
||||
let lowerThreshold = -Infinity;
|
||||
Object.defineProperty(this, "lowerThreshold", {
|
||||
get: function() {
|
||||
return lowerThreshold;
|
||||
},
|
||||
set: function(value) {
|
||||
lowerThreshold = value;
|
||||
this.sliceList.forEach(function(slice) {
|
||||
slice.geometryNeedsUpdate = true;
|
||||
});
|
||||
}
|
||||
});
|
||||
let upperThreshold = Infinity;
|
||||
Object.defineProperty(this, "upperThreshold", {
|
||||
get: function() {
|
||||
return upperThreshold;
|
||||
},
|
||||
set: function(value) {
|
||||
upperThreshold = value;
|
||||
this.sliceList.forEach(function(slice) {
|
||||
slice.geometryNeedsUpdate = true;
|
||||
});
|
||||
}
|
||||
});
|
||||
this.sliceList = [];
|
||||
this.segmentation = false;
|
||||
}
|
||||
/**
|
||||
* @member {Function} getData Shortcut for data[access(i,j,k)]
|
||||
* @memberof Volume
|
||||
* @param {number} i First coordinate
|
||||
* @param {number} j Second coordinate
|
||||
* @param {number} k Third coordinate
|
||||
* @returns {number} value in the data array
|
||||
*/
|
||||
getData(i, j, k) {
|
||||
return this.data[k * this.xLength * this.yLength + j * this.xLength + i];
|
||||
}
|
||||
/**
|
||||
* @member {Function} access compute the index in the data array corresponding to the given coordinates in IJK system
|
||||
* @memberof Volume
|
||||
* @param {number} i First coordinate
|
||||
* @param {number} j Second coordinate
|
||||
* @param {number} k Third coordinate
|
||||
* @returns {number} index
|
||||
*/
|
||||
access(i, j, k) {
|
||||
return k * this.xLength * this.yLength + j * this.xLength + i;
|
||||
}
|
||||
/**
|
||||
* @member {Function} reverseAccess Retrieve the IJK coordinates of the voxel corresponding of the given index in the data
|
||||
* @memberof Volume
|
||||
* @param {number} index index of the voxel
|
||||
* @returns {Array} [x,y,z]
|
||||
*/
|
||||
reverseAccess(index) {
|
||||
const z = Math.floor(index / (this.yLength * this.xLength));
|
||||
const y = Math.floor((index - z * this.yLength * this.xLength) / this.xLength);
|
||||
const x = index - z * this.yLength * this.xLength - y * this.xLength;
|
||||
return [x, y, z];
|
||||
}
|
||||
/**
|
||||
* @member {Function} map Apply a function to all the voxels, be careful, the value will be replaced
|
||||
* @memberof Volume
|
||||
* @param {Function} functionToMap A function to apply to every voxel, will be called with the following parameters :
|
||||
* value of the voxel
|
||||
* index of the voxel
|
||||
* the data (TypedArray)
|
||||
* @param {Object} context You can specify a context in which call the function, default if this Volume
|
||||
* @returns {Volume} this
|
||||
*/
|
||||
map(functionToMap, context) {
|
||||
const length = this.data.length;
|
||||
context = context || this;
|
||||
for (let i = 0; i < length; i++) {
|
||||
this.data[i] = functionToMap.call(context, this.data[i], i, this.data);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* @member {Function} extractPerpendicularPlane Compute the orientation of the slice and returns all the information relative to the geometry such as sliceAccess, the plane matrix (orientation and position in RAS coordinate) and the dimensions of the plane in both coordinate system.
|
||||
* @memberof Volume
|
||||
* @param {string} axis the normal axis to the slice 'x' 'y' or 'z'
|
||||
* @param {number} index the index of the slice
|
||||
* @returns {Object} an object containing all the usefull information on the geometry of the slice
|
||||
*/
|
||||
extractPerpendicularPlane(axis, RASIndex) {
|
||||
let firstSpacing, secondSpacing, positionOffset, IJKIndex;
|
||||
const axisInIJK = new Vector3(), firstDirection = new Vector3(), secondDirection = new Vector3(), planeMatrix = new Matrix4().identity(), volume = this;
|
||||
const dimensions = new Vector3(this.xLength, this.yLength, this.zLength);
|
||||
switch (axis) {
|
||||
case "x":
|
||||
axisInIJK.set(1, 0, 0);
|
||||
firstDirection.set(0, 0, -1);
|
||||
secondDirection.set(0, -1, 0);
|
||||
firstSpacing = this.spacing[this.axisOrder.indexOf("z")];
|
||||
secondSpacing = this.spacing[this.axisOrder.indexOf("y")];
|
||||
IJKIndex = new Vector3(RASIndex, 0, 0);
|
||||
planeMatrix.multiply(new Matrix4().makeRotationY(Math.PI / 2));
|
||||
positionOffset = (volume.RASDimensions[0] - 1) / 2;
|
||||
planeMatrix.setPosition(new Vector3(RASIndex - positionOffset, 0, 0));
|
||||
break;
|
||||
case "y":
|
||||
axisInIJK.set(0, 1, 0);
|
||||
firstDirection.set(1, 0, 0);
|
||||
secondDirection.set(0, 0, 1);
|
||||
firstSpacing = this.spacing[this.axisOrder.indexOf("x")];
|
||||
secondSpacing = this.spacing[this.axisOrder.indexOf("z")];
|
||||
IJKIndex = new Vector3(0, RASIndex, 0);
|
||||
planeMatrix.multiply(new Matrix4().makeRotationX(-Math.PI / 2));
|
||||
positionOffset = (volume.RASDimensions[1] - 1) / 2;
|
||||
planeMatrix.setPosition(new Vector3(0, RASIndex - positionOffset, 0));
|
||||
break;
|
||||
case "z":
|
||||
default:
|
||||
axisInIJK.set(0, 0, 1);
|
||||
firstDirection.set(1, 0, 0);
|
||||
secondDirection.set(0, -1, 0);
|
||||
firstSpacing = this.spacing[this.axisOrder.indexOf("x")];
|
||||
secondSpacing = this.spacing[this.axisOrder.indexOf("y")];
|
||||
IJKIndex = new Vector3(0, 0, RASIndex);
|
||||
positionOffset = (volume.RASDimensions[2] - 1) / 2;
|
||||
planeMatrix.setPosition(new Vector3(0, 0, RASIndex - positionOffset));
|
||||
break;
|
||||
}
|
||||
let iLength, jLength;
|
||||
if (!this.segmentation) {
|
||||
firstDirection.applyMatrix4(volume.inverseMatrix).normalize();
|
||||
secondDirection.applyMatrix4(volume.inverseMatrix).normalize();
|
||||
axisInIJK.applyMatrix4(volume.inverseMatrix).normalize();
|
||||
}
|
||||
firstDirection.arglet = "i";
|
||||
secondDirection.arglet = "j";
|
||||
iLength = Math.floor(Math.abs(firstDirection.dot(dimensions)));
|
||||
jLength = Math.floor(Math.abs(secondDirection.dot(dimensions)));
|
||||
const planeWidth = Math.abs(iLength * firstSpacing);
|
||||
const planeHeight = Math.abs(jLength * secondSpacing);
|
||||
IJKIndex = Math.abs(Math.round(IJKIndex.applyMatrix4(volume.inverseMatrix).dot(axisInIJK)));
|
||||
const base = [new Vector3(1, 0, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1)];
|
||||
const iDirection = [firstDirection, secondDirection, axisInIJK].find(function(x) {
|
||||
return Math.abs(x.dot(base[0])) > 0.9;
|
||||
});
|
||||
const jDirection = [firstDirection, secondDirection, axisInIJK].find(function(x) {
|
||||
return Math.abs(x.dot(base[1])) > 0.9;
|
||||
});
|
||||
const kDirection = [firstDirection, secondDirection, axisInIJK].find(function(x) {
|
||||
return Math.abs(x.dot(base[2])) > 0.9;
|
||||
});
|
||||
function sliceAccess(i, j) {
|
||||
const si = iDirection === axisInIJK ? IJKIndex : iDirection.arglet === "i" ? i : j;
|
||||
const sj = jDirection === axisInIJK ? IJKIndex : jDirection.arglet === "i" ? i : j;
|
||||
const sk = kDirection === axisInIJK ? IJKIndex : kDirection.arglet === "i" ? i : j;
|
||||
const accessI = iDirection.dot(base[0]) > 0 ? si : volume.xLength - 1 - si;
|
||||
const accessJ = jDirection.dot(base[1]) > 0 ? sj : volume.yLength - 1 - sj;
|
||||
const accessK = kDirection.dot(base[2]) > 0 ? sk : volume.zLength - 1 - sk;
|
||||
return volume.access(accessI, accessJ, accessK);
|
||||
}
|
||||
return {
|
||||
iLength,
|
||||
jLength,
|
||||
sliceAccess,
|
||||
matrix: planeMatrix,
|
||||
planeWidth,
|
||||
planeHeight
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @member {Function} extractSlice Returns a slice corresponding to the given axis and index
|
||||
* The coordinate are given in the Right Anterior Superior coordinate format
|
||||
* @memberof Volume
|
||||
* @param {string} axis the normal axis to the slice 'x' 'y' or 'z'
|
||||
* @param {number} index the index of the slice
|
||||
* @returns {VolumeSlice} the extracted slice
|
||||
*/
|
||||
extractSlice(axis, index) {
|
||||
const slice = new VolumeSlice(this, index, axis);
|
||||
this.sliceList.push(slice);
|
||||
return slice;
|
||||
}
|
||||
/**
|
||||
* @member {Function} repaintAllSlices Call repaint on all the slices extracted from this volume
|
||||
* @see VolumeSlice.repaint
|
||||
* @memberof Volume
|
||||
* @returns {Volume} this
|
||||
*/
|
||||
repaintAllSlices() {
|
||||
this.sliceList.forEach(function(slice) {
|
||||
slice.repaint();
|
||||
});
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* @member {Function} computeMinMax Compute the minimum and the maximum of the data in the volume
|
||||
* @memberof Volume
|
||||
* @returns {Array} [min,max]
|
||||
*/
|
||||
computeMinMax() {
|
||||
let min = Infinity;
|
||||
let max = -Infinity;
|
||||
const datasize = this.data.length;
|
||||
let i = 0;
|
||||
for (i = 0; i < datasize; i++) {
|
||||
if (!isNaN(this.data[i])) {
|
||||
const value = this.data[i];
|
||||
min = Math.min(min, value);
|
||||
max = Math.max(max, value);
|
||||
}
|
||||
}
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
return [min, max];
|
||||
}
|
||||
}
|
||||
export {
|
||||
Volume
|
||||
};
|
||||
//# sourceMappingURL=Volume.js.map
|
||||
1
node_modules/three-stdlib/misc/Volume.js.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/Volume.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
115
node_modules/three-stdlib/misc/VolumeSlice.cjs
generated
vendored
Normal file
115
node_modules/three-stdlib/misc/VolumeSlice.cjs
generated
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
||||
const THREE = require("three");
|
||||
class VolumeSlice {
|
||||
constructor(volume, index, axis) {
|
||||
const slice = this;
|
||||
this.volume = volume;
|
||||
index = index || 0;
|
||||
Object.defineProperty(this, "index", {
|
||||
get: function() {
|
||||
return index;
|
||||
},
|
||||
set: function(value) {
|
||||
index = value;
|
||||
slice.geometryNeedsUpdate = true;
|
||||
return index;
|
||||
}
|
||||
});
|
||||
this.axis = axis || "z";
|
||||
this.canvas = document.createElement("canvas");
|
||||
this.canvasBuffer = document.createElement("canvas");
|
||||
this.updateGeometry();
|
||||
const canvasMap = new THREE.Texture(this.canvas);
|
||||
canvasMap.minFilter = THREE.LinearFilter;
|
||||
canvasMap.wrapS = canvasMap.wrapT = THREE.ClampToEdgeWrapping;
|
||||
if ("colorSpace" in canvasMap)
|
||||
canvasMap.colorSpace = "srgb";
|
||||
else
|
||||
canvasMap.encoding = 3001;
|
||||
const material = new THREE.MeshBasicMaterial({ map: canvasMap, side: THREE.DoubleSide, transparent: true });
|
||||
this.mesh = new THREE.Mesh(this.geometry, material);
|
||||
this.mesh.matrixAutoUpdate = false;
|
||||
this.geometryNeedsUpdate = true;
|
||||
this.repaint();
|
||||
}
|
||||
/**
|
||||
* @member {Function} repaint Refresh the texture and the geometry if geometryNeedsUpdate is set to true
|
||||
* @memberof VolumeSlice
|
||||
*/
|
||||
repaint() {
|
||||
if (this.geometryNeedsUpdate) {
|
||||
this.updateGeometry();
|
||||
}
|
||||
const iLength = this.iLength, jLength = this.jLength, sliceAccess = this.sliceAccess, volume = this.volume, canvas = this.canvasBuffer, ctx = this.ctxBuffer;
|
||||
const imgData = ctx.getImageData(0, 0, iLength, jLength);
|
||||
const data = imgData.data;
|
||||
const volumeData = volume.data;
|
||||
const upperThreshold = volume.upperThreshold;
|
||||
const lowerThreshold = volume.lowerThreshold;
|
||||
const windowLow = volume.windowLow;
|
||||
const windowHigh = volume.windowHigh;
|
||||
let pixelCount = 0;
|
||||
if (volume.dataType === "label") {
|
||||
for (let j = 0; j < jLength; j++) {
|
||||
for (let i = 0; i < iLength; i++) {
|
||||
let label = volumeData[sliceAccess(i, j)];
|
||||
label = label >= this.colorMap.length ? label % this.colorMap.length + 1 : label;
|
||||
const color = this.colorMap[label];
|
||||
data[4 * pixelCount] = color >> 24 & 255;
|
||||
data[4 * pixelCount + 1] = color >> 16 & 255;
|
||||
data[4 * pixelCount + 2] = color >> 8 & 255;
|
||||
data[4 * pixelCount + 3] = color & 255;
|
||||
pixelCount++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let j = 0; j < jLength; j++) {
|
||||
for (let i = 0; i < iLength; i++) {
|
||||
let value = volumeData[sliceAccess(i, j)];
|
||||
let alpha = 255;
|
||||
alpha = upperThreshold >= value ? lowerThreshold <= value ? alpha : 0 : 0;
|
||||
value = Math.floor(255 * (value - windowLow) / (windowHigh - windowLow));
|
||||
value = value > 255 ? 255 : value < 0 ? 0 : value | 0;
|
||||
data[4 * pixelCount] = value;
|
||||
data[4 * pixelCount + 1] = value;
|
||||
data[4 * pixelCount + 2] = value;
|
||||
data[4 * pixelCount + 3] = alpha;
|
||||
pixelCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx.putImageData(imgData, 0, 0);
|
||||
this.ctx.drawImage(canvas, 0, 0, iLength, jLength, 0, 0, this.canvas.width, this.canvas.height);
|
||||
this.mesh.material.map.needsUpdate = true;
|
||||
}
|
||||
/**
|
||||
* @member {Function} Refresh the geometry according to axis and index
|
||||
* @see Volume.extractPerpendicularPlane
|
||||
* @memberof VolumeSlice
|
||||
*/
|
||||
updateGeometry() {
|
||||
const extracted = this.volume.extractPerpendicularPlane(this.axis, this.index);
|
||||
this.sliceAccess = extracted.sliceAccess;
|
||||
this.jLength = extracted.jLength;
|
||||
this.iLength = extracted.iLength;
|
||||
this.matrix = extracted.matrix;
|
||||
this.canvas.width = extracted.planeWidth;
|
||||
this.canvas.height = extracted.planeHeight;
|
||||
this.canvasBuffer.width = this.iLength;
|
||||
this.canvasBuffer.height = this.jLength;
|
||||
this.ctx = this.canvas.getContext("2d");
|
||||
this.ctxBuffer = this.canvasBuffer.getContext("2d");
|
||||
if (this.geometry)
|
||||
this.geometry.dispose();
|
||||
this.geometry = new THREE.PlaneGeometry(extracted.planeWidth, extracted.planeHeight);
|
||||
if (this.mesh) {
|
||||
this.mesh.geometry = this.geometry;
|
||||
this.mesh.matrix.identity();
|
||||
this.mesh.applyMatrix4(this.matrix);
|
||||
}
|
||||
this.geometryNeedsUpdate = false;
|
||||
}
|
||||
}
|
||||
exports.VolumeSlice = VolumeSlice;
|
||||
//# sourceMappingURL=VolumeSlice.cjs.map
|
||||
1
node_modules/three-stdlib/misc/VolumeSlice.cjs.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/VolumeSlice.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
28
node_modules/three-stdlib/misc/VolumeSlice.d.ts
generated
vendored
Normal file
28
node_modules/three-stdlib/misc/VolumeSlice.d.ts
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
import { Matrix3, Mesh } from 'three'
|
||||
|
||||
import { Volume } from './Volume'
|
||||
|
||||
export class VolumeSlice {
|
||||
constructor(volume: Volume, index?: number, axis?: string)
|
||||
|
||||
index: number
|
||||
axis: string
|
||||
|
||||
canvas: HTMLCanvasElement
|
||||
canvasBuffer: HTMLCanvasElement
|
||||
|
||||
ctx: CanvasRenderingContext2D
|
||||
ctxBuffer: CanvasRenderingContext2D
|
||||
|
||||
mesh: Mesh
|
||||
|
||||
geometryNeedsUpdate: boolean
|
||||
|
||||
sliceAccess: number
|
||||
jLength: number
|
||||
iLength: number
|
||||
matrix: Matrix3
|
||||
|
||||
repaint(): void
|
||||
updateGeometry(): void
|
||||
}
|
||||
115
node_modules/three-stdlib/misc/VolumeSlice.js
generated
vendored
Normal file
115
node_modules/three-stdlib/misc/VolumeSlice.js
generated
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
import { Texture, LinearFilter, ClampToEdgeWrapping, MeshBasicMaterial, DoubleSide, Mesh, PlaneGeometry } from "three";
|
||||
class VolumeSlice {
|
||||
constructor(volume, index, axis) {
|
||||
const slice = this;
|
||||
this.volume = volume;
|
||||
index = index || 0;
|
||||
Object.defineProperty(this, "index", {
|
||||
get: function() {
|
||||
return index;
|
||||
},
|
||||
set: function(value) {
|
||||
index = value;
|
||||
slice.geometryNeedsUpdate = true;
|
||||
return index;
|
||||
}
|
||||
});
|
||||
this.axis = axis || "z";
|
||||
this.canvas = document.createElement("canvas");
|
||||
this.canvasBuffer = document.createElement("canvas");
|
||||
this.updateGeometry();
|
||||
const canvasMap = new Texture(this.canvas);
|
||||
canvasMap.minFilter = LinearFilter;
|
||||
canvasMap.wrapS = canvasMap.wrapT = ClampToEdgeWrapping;
|
||||
if ("colorSpace" in canvasMap)
|
||||
canvasMap.colorSpace = "srgb";
|
||||
else
|
||||
canvasMap.encoding = 3001;
|
||||
const material = new MeshBasicMaterial({ map: canvasMap, side: DoubleSide, transparent: true });
|
||||
this.mesh = new Mesh(this.geometry, material);
|
||||
this.mesh.matrixAutoUpdate = false;
|
||||
this.geometryNeedsUpdate = true;
|
||||
this.repaint();
|
||||
}
|
||||
/**
|
||||
* @member {Function} repaint Refresh the texture and the geometry if geometryNeedsUpdate is set to true
|
||||
* @memberof VolumeSlice
|
||||
*/
|
||||
repaint() {
|
||||
if (this.geometryNeedsUpdate) {
|
||||
this.updateGeometry();
|
||||
}
|
||||
const iLength = this.iLength, jLength = this.jLength, sliceAccess = this.sliceAccess, volume = this.volume, canvas = this.canvasBuffer, ctx = this.ctxBuffer;
|
||||
const imgData = ctx.getImageData(0, 0, iLength, jLength);
|
||||
const data = imgData.data;
|
||||
const volumeData = volume.data;
|
||||
const upperThreshold = volume.upperThreshold;
|
||||
const lowerThreshold = volume.lowerThreshold;
|
||||
const windowLow = volume.windowLow;
|
||||
const windowHigh = volume.windowHigh;
|
||||
let pixelCount = 0;
|
||||
if (volume.dataType === "label") {
|
||||
for (let j = 0; j < jLength; j++) {
|
||||
for (let i = 0; i < iLength; i++) {
|
||||
let label = volumeData[sliceAccess(i, j)];
|
||||
label = label >= this.colorMap.length ? label % this.colorMap.length + 1 : label;
|
||||
const color = this.colorMap[label];
|
||||
data[4 * pixelCount] = color >> 24 & 255;
|
||||
data[4 * pixelCount + 1] = color >> 16 & 255;
|
||||
data[4 * pixelCount + 2] = color >> 8 & 255;
|
||||
data[4 * pixelCount + 3] = color & 255;
|
||||
pixelCount++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let j = 0; j < jLength; j++) {
|
||||
for (let i = 0; i < iLength; i++) {
|
||||
let value = volumeData[sliceAccess(i, j)];
|
||||
let alpha = 255;
|
||||
alpha = upperThreshold >= value ? lowerThreshold <= value ? alpha : 0 : 0;
|
||||
value = Math.floor(255 * (value - windowLow) / (windowHigh - windowLow));
|
||||
value = value > 255 ? 255 : value < 0 ? 0 : value | 0;
|
||||
data[4 * pixelCount] = value;
|
||||
data[4 * pixelCount + 1] = value;
|
||||
data[4 * pixelCount + 2] = value;
|
||||
data[4 * pixelCount + 3] = alpha;
|
||||
pixelCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx.putImageData(imgData, 0, 0);
|
||||
this.ctx.drawImage(canvas, 0, 0, iLength, jLength, 0, 0, this.canvas.width, this.canvas.height);
|
||||
this.mesh.material.map.needsUpdate = true;
|
||||
}
|
||||
/**
|
||||
* @member {Function} Refresh the geometry according to axis and index
|
||||
* @see Volume.extractPerpendicularPlane
|
||||
* @memberof VolumeSlice
|
||||
*/
|
||||
updateGeometry() {
|
||||
const extracted = this.volume.extractPerpendicularPlane(this.axis, this.index);
|
||||
this.sliceAccess = extracted.sliceAccess;
|
||||
this.jLength = extracted.jLength;
|
||||
this.iLength = extracted.iLength;
|
||||
this.matrix = extracted.matrix;
|
||||
this.canvas.width = extracted.planeWidth;
|
||||
this.canvas.height = extracted.planeHeight;
|
||||
this.canvasBuffer.width = this.iLength;
|
||||
this.canvasBuffer.height = this.jLength;
|
||||
this.ctx = this.canvas.getContext("2d");
|
||||
this.ctxBuffer = this.canvasBuffer.getContext("2d");
|
||||
if (this.geometry)
|
||||
this.geometry.dispose();
|
||||
this.geometry = new PlaneGeometry(extracted.planeWidth, extracted.planeHeight);
|
||||
if (this.mesh) {
|
||||
this.mesh.geometry = this.geometry;
|
||||
this.mesh.matrix.identity();
|
||||
this.mesh.applyMatrix4(this.matrix);
|
||||
}
|
||||
this.geometryNeedsUpdate = false;
|
||||
}
|
||||
}
|
||||
export {
|
||||
VolumeSlice
|
||||
};
|
||||
//# sourceMappingURL=VolumeSlice.js.map
|
||||
1
node_modules/three-stdlib/misc/VolumeSlice.js.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/VolumeSlice.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
75
node_modules/three-stdlib/misc/WebGL.cjs
generated
vendored
Normal file
75
node_modules/three-stdlib/misc/WebGL.cjs
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
||||
let webGLAvailable, webGL2Available;
|
||||
function isWebGLAvailable() {
|
||||
var _a;
|
||||
if (webGLAvailable !== void 0)
|
||||
return webGLAvailable;
|
||||
try {
|
||||
let gl;
|
||||
const canvas = document.createElement("canvas");
|
||||
webGLAvailable = !!(window.WebGLRenderingContext && (gl = canvas.getContext("webgl")));
|
||||
if (gl)
|
||||
(_a = gl.getExtension("WEBGL_lose_context")) == null ? void 0 : _a.loseContext();
|
||||
return webGLAvailable;
|
||||
} catch (e) {
|
||||
return webGLAvailable = false;
|
||||
}
|
||||
}
|
||||
function isWebGL2Available() {
|
||||
var _a;
|
||||
if (webGL2Available !== void 0)
|
||||
return webGL2Available;
|
||||
try {
|
||||
let gl;
|
||||
const canvas = document.createElement("canvas");
|
||||
webGL2Available = !!(window.WebGL2RenderingContext && (gl = canvas.getContext("webgl2")));
|
||||
if (gl)
|
||||
(_a = gl.getExtension("WEBGL_lose_context")) == null ? void 0 : _a.loseContext();
|
||||
return webGL2Available;
|
||||
} catch (e) {
|
||||
return webGL2Available = false;
|
||||
}
|
||||
}
|
||||
function getWebGLErrorMessage() {
|
||||
return getErrorMessage(1);
|
||||
}
|
||||
function getWebGL2ErrorMessage() {
|
||||
return getErrorMessage(2);
|
||||
}
|
||||
function getErrorMessage(version) {
|
||||
const names = {
|
||||
1: "WebGL",
|
||||
2: "WebGL 2"
|
||||
};
|
||||
const contexts = {
|
||||
1: window.WebGLRenderingContext,
|
||||
2: window.WebGL2RenderingContext
|
||||
};
|
||||
const element = document.createElement("div");
|
||||
element.id = "webglmessage";
|
||||
element.style.fontFamily = "monospace";
|
||||
element.style.fontSize = "13px";
|
||||
element.style.fontWeight = "normal";
|
||||
element.style.textAlign = "center";
|
||||
element.style.background = "#fff";
|
||||
element.style.color = "#000";
|
||||
element.style.padding = "1.5em";
|
||||
element.style.width = "400px";
|
||||
element.style.margin = "5em auto 0";
|
||||
let message = 'Your $0 does not seem to support <a href="http://khronos.org/webgl/wiki/Getting_a_WebGL_Implementation" style="color:#000">$1</a>';
|
||||
if (contexts[version]) {
|
||||
message = message.replace("$0", "graphics card");
|
||||
} else {
|
||||
message = message.replace("$0", "browser");
|
||||
}
|
||||
message = message.replace("$1", names[version]);
|
||||
element.innerHTML = message;
|
||||
return element;
|
||||
}
|
||||
exports.getErrorMessage = getErrorMessage;
|
||||
exports.getWebGL2ErrorMessage = getWebGL2ErrorMessage;
|
||||
exports.getWebGLErrorMessage = getWebGLErrorMessage;
|
||||
exports.isWebGL2Available = isWebGL2Available;
|
||||
exports.isWebGLAvailable = isWebGLAvailable;
|
||||
//# sourceMappingURL=WebGL.cjs.map
|
||||
1
node_modules/three-stdlib/misc/WebGL.cjs.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/WebGL.cjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"WebGL.cjs","sources":["../../src/misc/WebGL.ts"],"sourcesContent":["let webGLAvailable: boolean, webGL2Available: boolean\n\nexport function isWebGLAvailable(): boolean {\n if (webGLAvailable !== undefined) return webGLAvailable\n try {\n let gl\n const canvas = document.createElement('canvas')\n webGLAvailable = !!(window.WebGLRenderingContext && (gl = canvas.getContext('webgl')))\n if (gl) gl.getExtension('WEBGL_lose_context')?.loseContext()\n return webGLAvailable\n } catch (e) {\n return (webGLAvailable = false)\n }\n}\n\nexport function isWebGL2Available(): boolean {\n if (webGL2Available !== undefined) return webGL2Available\n try {\n let gl\n const canvas = document.createElement('canvas')\n webGL2Available = !!(window.WebGL2RenderingContext && (gl = canvas.getContext('webgl2')))\n if (gl) gl.getExtension('WEBGL_lose_context')?.loseContext()\n return webGL2Available\n } catch (e) {\n return (webGL2Available = false)\n }\n}\n\nexport function getWebGLErrorMessage(): HTMLDivElement {\n return getErrorMessage(1)\n}\n\nexport function getWebGL2ErrorMessage(): HTMLDivElement {\n return getErrorMessage(2)\n}\n\nexport function getErrorMessage(version: 1 | 2): HTMLDivElement {\n const names = {\n 1: 'WebGL',\n 2: 'WebGL 2',\n }\n\n const contexts = {\n 1: window.WebGLRenderingContext,\n 2: window.WebGL2RenderingContext,\n }\n\n const element = document.createElement('div')\n element.id = 'webglmessage'\n element.style.fontFamily = 'monospace'\n element.style.fontSize = '13px'\n element.style.fontWeight = 'normal'\n element.style.textAlign = 'center'\n element.style.background = '#fff'\n element.style.color = '#000'\n element.style.padding = '1.5em'\n element.style.width = '400px'\n element.style.margin = '5em auto 0'\n\n let message =\n 'Your $0 does not seem to support <a href=\"http://khronos.org/webgl/wiki/Getting_a_WebGL_Implementation\" style=\"color:#000\">$1</a>'\n\n if (contexts[version]) {\n message = message.replace('$0', 'graphics card')\n } else {\n message = message.replace('$0', 'browser')\n }\n\n message = message.replace('$1', names[version])\n element.innerHTML = message\n return element\n}\n"],"names":[],"mappings":";;AAAA,IAAI,gBAAyB;AAEtB,SAAS,mBAA4B;;AAC1C,MAAI,mBAAmB;AAAkB,WAAA;AACrC,MAAA;AACE,QAAA;AACE,UAAA,SAAS,SAAS,cAAc,QAAQ;AAC9C,qBAAiB,CAAC,EAAE,OAAO,0BAA0B,KAAK,OAAO,WAAW,OAAO;AAC/E,QAAA;AAAO,eAAA,aAAa,oBAAoB,MAAjC,mBAAoC;AACxC,WAAA;AAAA,WACA;AACP,WAAQ,iBAAiB;AAAA,EAC3B;AACF;AAEO,SAAS,oBAA6B;;AAC3C,MAAI,oBAAoB;AAAkB,WAAA;AACtC,MAAA;AACE,QAAA;AACE,UAAA,SAAS,SAAS,cAAc,QAAQ;AAC9C,sBAAkB,CAAC,EAAE,OAAO,2BAA2B,KAAK,OAAO,WAAW,QAAQ;AAClF,QAAA;AAAO,eAAA,aAAa,oBAAoB,MAAjC,mBAAoC;AACxC,WAAA;AAAA,WACA;AACP,WAAQ,kBAAkB;AAAA,EAC5B;AACF;AAEO,SAAS,uBAAuC;AACrD,SAAO,gBAAgB,CAAC;AAC1B;AAEO,SAAS,wBAAwC;AACtD,SAAO,gBAAgB,CAAC;AAC1B;AAEO,SAAS,gBAAgB,SAAgC;AAC9D,QAAM,QAAQ;AAAA,IACZ,GAAG;AAAA,IACH,GAAG;AAAA,EAAA;AAGL,QAAM,WAAW;AAAA,IACf,GAAG,OAAO;AAAA,IACV,GAAG,OAAO;AAAA,EAAA;AAGN,QAAA,UAAU,SAAS,cAAc,KAAK;AAC5C,UAAQ,KAAK;AACb,UAAQ,MAAM,aAAa;AAC3B,UAAQ,MAAM,WAAW;AACzB,UAAQ,MAAM,aAAa;AAC3B,UAAQ,MAAM,YAAY;AAC1B,UAAQ,MAAM,aAAa;AAC3B,UAAQ,MAAM,QAAQ;AACtB,UAAQ,MAAM,UAAU;AACxB,UAAQ,MAAM,QAAQ;AACtB,UAAQ,MAAM,SAAS;AAEvB,MAAI,UACF;AAEE,MAAA,SAAS,OAAO,GAAG;AACX,cAAA,QAAQ,QAAQ,MAAM,eAAe;AAAA,EAAA,OAC1C;AACK,cAAA,QAAQ,QAAQ,MAAM,SAAS;AAAA,EAC3C;AAEA,YAAU,QAAQ,QAAQ,MAAM,MAAM,OAAO,CAAC;AAC9C,UAAQ,YAAY;AACb,SAAA;AACT;;;;;;"}
|
||||
5
node_modules/three-stdlib/misc/WebGL.d.ts
generated
vendored
Normal file
5
node_modules/three-stdlib/misc/WebGL.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
export declare function isWebGLAvailable(): boolean;
|
||||
export declare function isWebGL2Available(): boolean;
|
||||
export declare function getWebGLErrorMessage(): HTMLDivElement;
|
||||
export declare function getWebGL2ErrorMessage(): HTMLDivElement;
|
||||
export declare function getErrorMessage(version: 1 | 2): HTMLDivElement;
|
||||
75
node_modules/three-stdlib/misc/WebGL.js
generated
vendored
Normal file
75
node_modules/three-stdlib/misc/WebGL.js
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
let webGLAvailable, webGL2Available;
|
||||
function isWebGLAvailable() {
|
||||
var _a;
|
||||
if (webGLAvailable !== void 0)
|
||||
return webGLAvailable;
|
||||
try {
|
||||
let gl;
|
||||
const canvas = document.createElement("canvas");
|
||||
webGLAvailable = !!(window.WebGLRenderingContext && (gl = canvas.getContext("webgl")));
|
||||
if (gl)
|
||||
(_a = gl.getExtension("WEBGL_lose_context")) == null ? void 0 : _a.loseContext();
|
||||
return webGLAvailable;
|
||||
} catch (e) {
|
||||
return webGLAvailable = false;
|
||||
}
|
||||
}
|
||||
function isWebGL2Available() {
|
||||
var _a;
|
||||
if (webGL2Available !== void 0)
|
||||
return webGL2Available;
|
||||
try {
|
||||
let gl;
|
||||
const canvas = document.createElement("canvas");
|
||||
webGL2Available = !!(window.WebGL2RenderingContext && (gl = canvas.getContext("webgl2")));
|
||||
if (gl)
|
||||
(_a = gl.getExtension("WEBGL_lose_context")) == null ? void 0 : _a.loseContext();
|
||||
return webGL2Available;
|
||||
} catch (e) {
|
||||
return webGL2Available = false;
|
||||
}
|
||||
}
|
||||
function getWebGLErrorMessage() {
|
||||
return getErrorMessage(1);
|
||||
}
|
||||
function getWebGL2ErrorMessage() {
|
||||
return getErrorMessage(2);
|
||||
}
|
||||
function getErrorMessage(version) {
|
||||
const names = {
|
||||
1: "WebGL",
|
||||
2: "WebGL 2"
|
||||
};
|
||||
const contexts = {
|
||||
1: window.WebGLRenderingContext,
|
||||
2: window.WebGL2RenderingContext
|
||||
};
|
||||
const element = document.createElement("div");
|
||||
element.id = "webglmessage";
|
||||
element.style.fontFamily = "monospace";
|
||||
element.style.fontSize = "13px";
|
||||
element.style.fontWeight = "normal";
|
||||
element.style.textAlign = "center";
|
||||
element.style.background = "#fff";
|
||||
element.style.color = "#000";
|
||||
element.style.padding = "1.5em";
|
||||
element.style.width = "400px";
|
||||
element.style.margin = "5em auto 0";
|
||||
let message = 'Your $0 does not seem to support <a href="http://khronos.org/webgl/wiki/Getting_a_WebGL_Implementation" style="color:#000">$1</a>';
|
||||
if (contexts[version]) {
|
||||
message = message.replace("$0", "graphics card");
|
||||
} else {
|
||||
message = message.replace("$0", "browser");
|
||||
}
|
||||
message = message.replace("$1", names[version]);
|
||||
element.innerHTML = message;
|
||||
return element;
|
||||
}
|
||||
export {
|
||||
getErrorMessage,
|
||||
getWebGL2ErrorMessage,
|
||||
getWebGLErrorMessage,
|
||||
isWebGL2Available,
|
||||
isWebGLAvailable
|
||||
};
|
||||
//# sourceMappingURL=WebGL.js.map
|
||||
1
node_modules/three-stdlib/misc/WebGL.js.map
generated
vendored
Normal file
1
node_modules/three-stdlib/misc/WebGL.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"WebGL.js","sources":["../../src/misc/WebGL.ts"],"sourcesContent":["let webGLAvailable: boolean, webGL2Available: boolean\n\nexport function isWebGLAvailable(): boolean {\n if (webGLAvailable !== undefined) return webGLAvailable\n try {\n let gl\n const canvas = document.createElement('canvas')\n webGLAvailable = !!(window.WebGLRenderingContext && (gl = canvas.getContext('webgl')))\n if (gl) gl.getExtension('WEBGL_lose_context')?.loseContext()\n return webGLAvailable\n } catch (e) {\n return (webGLAvailable = false)\n }\n}\n\nexport function isWebGL2Available(): boolean {\n if (webGL2Available !== undefined) return webGL2Available\n try {\n let gl\n const canvas = document.createElement('canvas')\n webGL2Available = !!(window.WebGL2RenderingContext && (gl = canvas.getContext('webgl2')))\n if (gl) gl.getExtension('WEBGL_lose_context')?.loseContext()\n return webGL2Available\n } catch (e) {\n return (webGL2Available = false)\n }\n}\n\nexport function getWebGLErrorMessage(): HTMLDivElement {\n return getErrorMessage(1)\n}\n\nexport function getWebGL2ErrorMessage(): HTMLDivElement {\n return getErrorMessage(2)\n}\n\nexport function getErrorMessage(version: 1 | 2): HTMLDivElement {\n const names = {\n 1: 'WebGL',\n 2: 'WebGL 2',\n }\n\n const contexts = {\n 1: window.WebGLRenderingContext,\n 2: window.WebGL2RenderingContext,\n }\n\n const element = document.createElement('div')\n element.id = 'webglmessage'\n element.style.fontFamily = 'monospace'\n element.style.fontSize = '13px'\n element.style.fontWeight = 'normal'\n element.style.textAlign = 'center'\n element.style.background = '#fff'\n element.style.color = '#000'\n element.style.padding = '1.5em'\n element.style.width = '400px'\n element.style.margin = '5em auto 0'\n\n let message =\n 'Your $0 does not seem to support <a href=\"http://khronos.org/webgl/wiki/Getting_a_WebGL_Implementation\" style=\"color:#000\">$1</a>'\n\n if (contexts[version]) {\n message = message.replace('$0', 'graphics card')\n } else {\n message = message.replace('$0', 'browser')\n }\n\n message = message.replace('$1', names[version])\n element.innerHTML = message\n return element\n}\n"],"names":[],"mappings":"AAAA,IAAI,gBAAyB;AAEtB,SAAS,mBAA4B;AAF5C;AAGE,MAAI,mBAAmB;AAAkB,WAAA;AACrC,MAAA;AACE,QAAA;AACE,UAAA,SAAS,SAAS,cAAc,QAAQ;AAC9C,qBAAiB,CAAC,EAAE,OAAO,0BAA0B,KAAK,OAAO,WAAW,OAAO;AAC/E,QAAA;AAAO,eAAA,aAAa,oBAAoB,MAAjC,mBAAoC;AACxC,WAAA;AAAA,WACA;AACP,WAAQ,iBAAiB;AAAA,EAC3B;AACF;AAEO,SAAS,oBAA6B;AAf7C;AAgBE,MAAI,oBAAoB;AAAkB,WAAA;AACtC,MAAA;AACE,QAAA;AACE,UAAA,SAAS,SAAS,cAAc,QAAQ;AAC9C,sBAAkB,CAAC,EAAE,OAAO,2BAA2B,KAAK,OAAO,WAAW,QAAQ;AAClF,QAAA;AAAO,eAAA,aAAa,oBAAoB,MAAjC,mBAAoC;AACxC,WAAA;AAAA,WACA;AACP,WAAQ,kBAAkB;AAAA,EAC5B;AACF;AAEO,SAAS,uBAAuC;AACrD,SAAO,gBAAgB,CAAC;AAC1B;AAEO,SAAS,wBAAwC;AACtD,SAAO,gBAAgB,CAAC;AAC1B;AAEO,SAAS,gBAAgB,SAAgC;AAC9D,QAAM,QAAQ;AAAA,IACZ,GAAG;AAAA,IACH,GAAG;AAAA,EAAA;AAGL,QAAM,WAAW;AAAA,IACf,GAAG,OAAO;AAAA,IACV,GAAG,OAAO;AAAA,EAAA;AAGN,QAAA,UAAU,SAAS,cAAc,KAAK;AAC5C,UAAQ,KAAK;AACb,UAAQ,MAAM,aAAa;AAC3B,UAAQ,MAAM,WAAW;AACzB,UAAQ,MAAM,aAAa;AAC3B,UAAQ,MAAM,YAAY;AAC1B,UAAQ,MAAM,aAAa;AAC3B,UAAQ,MAAM,QAAQ;AACtB,UAAQ,MAAM,UAAU;AACxB,UAAQ,MAAM,QAAQ;AACtB,UAAQ,MAAM,SAAS;AAEvB,MAAI,UACF;AAEE,MAAA,SAAS,OAAO,GAAG;AACX,cAAA,QAAQ,QAAQ,MAAM,eAAe;AAAA,EAAA,OAC1C;AACK,cAAA,QAAQ,QAAQ,MAAM,SAAS;AAAA,EAC3C;AAEA,YAAU,QAAQ,QAAQ,MAAM,MAAM,OAAO,CAAC;AAC9C,UAAQ,YAAY;AACb,SAAA;AACT;"}
|
||||
Reference in New Issue
Block a user